From 5fc2067f98d131b0e4c5e547344873969b4b0921 Mon Sep 17 00:00:00 2001
From: mauritsvanrees
Date: Fri, 19 May 2023 23:57:46 +0200
Subject: [PATCH] [fc] Repository: plone.batching
Branch: refs/heads/master
Date: 2023-05-19T14:37:17+02:00
Author: Maurits van Rees (mauritsvanrees)
Commit: https://github.com/plone/plone.batching/commit/fbba68ce484cce2550c620234798501424cddd44
Configuring with plone/meta
Files changed:
A news/50c0e759.internal
M .meta.toml
M .pre-commit-config.yaml
M tox.ini
Repository: plone.batching
Branch: refs/heads/master
Date: 2023-05-19T23:57:46+02:00
Author: Maurits van Rees (mauritsvanrees)
Commit: https://github.com/plone/plone.batching/commit/33ce4a23cb594abd4e2ee1f1fce200675d49e658
Merge pull request #49 from plone/config-with-default-template-e963330c
Configuring with plone/meta
Files changed:
A news/50c0e759.internal
M .meta.toml
M .pre-commit-config.yaml
M tox.ini
---
last_commit.txt | 1063 +----------------------------------------------
1 file changed, 19 insertions(+), 1044 deletions(-)
diff --git a/last_commit.txt b/last_commit.txt
index 6e034f14ef..388650a893 100644
--- a/last_commit.txt
+++ b/last_commit.txt
@@ -1,1063 +1,38 @@
-Repository: Products.CMFPlone
+Repository: plone.batching
-Branch: refs/heads/6.0.x
-Date: 2023-05-17T00:24:54+02:00
-Author: Gil Forcada Codinachs (gforcada)
-Commit: https://github.com/plone/Products.CMFPlone/commit/202aaf8f62406c910c26e083b5bda3e480291573
-
-Configuring with plone/meta
-
-Files changed:
-A .editorconfig
-A .meta.toml
-A .pre-commit-config.yaml
-A news/2a5f5557.internal
-A tox.ini
-M pyproject.toml
-M setup.cfg
-
-b'diff --git a/.editorconfig b/.editorconfig\nnew file mode 100644\nindex 0000000000..b4158b89d9\n--- /dev/null\n+++ b/.editorconfig\n@@ -0,0 +1,39 @@\n+# Generated from:\n+# https://github.com/plone/meta/tree/master/config/default\n+#\n+# EditorConfig Configuration file, for more details see:\n+# http://EditorConfig.org\n+# EditorConfig is a convention description, that could be interpreted\n+# by multiple editors to enforce common coding conventions for specific\n+# file types\n+\n+# top-most EditorConfig file:\n+# Will ignore other EditorConfig files in Home directory or upper tree level.\n+root = true\n+\n+\n+[*] # For All Files\n+# Unix-style newlines with a newline ending every file\n+end_of_line = lf\n+insert_final_newline = true\n+trim_trailing_whitespace = true\n+# Set default charset\n+charset = utf-8\n+# Indent style default\n+indent_style = space\n+# Max Line Length - a hard line wrap, should be disabled\n+max_line_length = off\n+\n+[*.{py,cfg,ini}]\n+# 4 space indentation\n+indent_size = 4\n+\n+[*.{yml,zpt,pt,dtml,zcml}]\n+# 2 space indentation\n+indent_size = 2\n+\n+[{Makefile,.gitmodules}]\n+# Tab indentation (no size specified, but view as 4 spaces)\n+indent_style = tab\n+indent_size = unset\n+tab_width = unset\ndiff --git a/.meta.toml b/.meta.toml\nnew file mode 100644\nindex 0000000000..c2597cca6f\n--- /dev/null\n+++ b/.meta.toml\n@@ -0,0 +1,5 @@\n+# Generated from:\n+# https://github.com/plone/meta/tree/master/config/default\n+[meta]\n+template = "default"\n+commit-id = "2a5f5557"\ndiff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml\nnew file mode 100644\nindex 0000000000..f9cdf5cd12\n--- /dev/null\n+++ b/.pre-commit-config.yaml\n@@ -0,0 +1,42 @@\n+# Generated from:\n+# https://github.com/plone/meta/tree/master/config/default\n+ci:\n+ autofix_prs: false\n+ autoupdate_schedule: monthly\n+\n+repos:\n+- repo: https://github.com/asottile/pyupgrade\n+ rev: v3.3.2\n+ hooks:\n+ - id: pyupgrade\n+ args: [--py38-plus]\n+- repo: https://github.com/pycqa/isort\n+ rev: 5.12.0\n+ hooks:\n+ - id: isort\n+- repo: https://github.com/psf/black\n+ rev: 23.3.0\n+ hooks:\n+ - id: black\n+- repo: https://github.com/collective/zpretty\n+ rev: 3.0.4\n+ hooks:\n+ - id: zpretty\n+- repo: https://github.com/PyCQA/flake8\n+ rev: 6.0.0\n+ hooks:\n+ - id: flake8\n+- repo: https://github.com/codespell-project/codespell\n+ rev: v2.2.4\n+ hooks:\n+ - id: codespell\n+ additional_dependencies:\n+ - tomli\n+- repo: https://github.com/mgedmin/check-manifest\n+ rev: "0.49"\n+ hooks:\n+ - id: check-manifest\n+- repo: https://github.com/regebro/pyroma\n+ rev: "4.2"\n+ hooks:\n+ - id: pyroma\ndiff --git a/news/2a5f5557.internal b/news/2a5f5557.internal\nnew file mode 100644\nindex 0000000000..c08f539916\n--- /dev/null\n+++ b/news/2a5f5557.internal\n@@ -0,0 +1,2 @@\n+Update configuration files.\n+[plone devs]\ndiff --git a/pyproject.toml b/pyproject.toml\nindex 10d43bb1bd..0c874a1b22 100644\n--- a/pyproject.toml\n+++ b/pyproject.toml\n@@ -1,3 +1,5 @@\n+# Generated from:\n+# https://github.com/plone/meta/tree/master/config/default\n [tool.towncrier]\n filename = "CHANGES.md"\n directory = "news/"\n@@ -20,3 +22,65 @@ showcontent = true\n directory = "bugfix"\n name = "Bug fixes:"\n showcontent = true\n+\n+[[tool.towncrier.type]]\n+directory = "internal"\n+name = "Internal:"\n+showcontent = true\n+\n+[[tool.towncrier.type]]\n+directory = "documentation"\n+name = "Documentation:"\n+showcontent = true\n+\n+[[tool.towncrier.type]]\n+directory = "tests"\n+name = "Tests"\n+showcontent = true\n+\n+[tool.isort]\n+profile = "plone"\n+\n+[tool.black]\n+target-version = ["py38"]\n+\n+\n+[tool.dependencychecker]\n+Zope = [\n+ # Zope own provided namespaces\n+ \'App\', \'OFS\', \'Products.Five\', \'Products.OFSP\', \'Products.PageTemplates\',\n+ \'Products.SiteAccess\', \'Shared\', \'Testing\', \'ZPublisher\', \'ZTUtils\',\n+ \'Zope2\', \'webdav\', \'zmi\',\n+ # ExtensionClass own provided namespaces\n+ \'ExtensionClass\', \'ComputedAttribute\', \'MethodObject\',\n+ # Zope dependencies\n+ \'AccessControl\', \'Acquisition\', \'AuthEncoding\', \'beautifulsoup4\', \'BTrees\',\n+ \'cffi\', \'Chameleon\', \'DateTime\', \'DocumentTemplate\',\n+ \'MultiMapping\', \'multipart\', \'PasteDeploy\', \'Persistence\', \'persistent\',\n+ \'pycparser\', \'python-gettext\', \'pytz\', \'RestrictedPython\', \'roman\',\n+ \'soupsieve\', \'transaction\', \'waitress\', \'WebOb\', \'WebTest\', \'WSGIProxy2\',\n+ \'z3c.pt\', \'zc.lockfile\', \'ZConfig\', \'zExceptions\', \'ZODB\', \'zodbpickle\',\n+ \'zope.annotation\', \'zope.browser\', \'zope.browsermenu\', \'zope.browserpage\',\n+ \'zope.browserresource\', \'zope.cachedescriptors\', \'zope.component\',\n+ \'zope.configuration\', \'zope.container\', \'zope.contentprovider\',\n+ \'zope.contenttype\', \'zope.datetime\', \'zope.deferredimport\',\n+ \'zope.deprecation\', \'zope.dottedname\', \'zope.event\', \'zope.exceptions\',\n+ \'zope.filerepresentation\', \'zope.globalrequest\', \'zope.hookable\',\n+ \'zope.i18n\', \'zope.i18nmessageid\', \'zope.interface\', \'zope.lifecycleevent\',\n+ \'zope.location\', \'zope.pagetemplate\', \'zope.processlifetime\', \'zope.proxy\',\n+ \'zope.ptresource\', \'zope.publisher\', \'zope.schema\', \'zope.security\',\n+ \'zope.sequencesort\', \'zope.site\', \'zope.size\', \'zope.structuredtext\',\n+ \'zope.tal\', \'zope.tales\', \'zope.testbrowser\', \'zope.testing\',\n+ \'zope.traversing\', \'zope.viewlet\'\n+]\n+\'Products.CMFCore\' = [\n+ \'docutils\', \'five.localsitemanager\', \'Missing\', \'Products.BTreeFolder2\',\n+ \'Products.GenericSetup\', \'Products.MailHost\', \'Products.PythonScripts\',\n+ \'Products.StandardCacheManagers\', \'Products.ZCatalog\', \'Record\',\n+ \'zope.sendmail\', \'Zope\'\n+]\n+\'plone.base\' = [\n+ \'plone.batching\', \'plone.registry\', \'plone.schema\',\'plone.z3cform\',\n+ \'Products.CMFCore\', \'Products.CMFDynamicViewFTI\',\n+]\n+python-dateutil = [\'dateutil\']\ndiff --git a/setup.cfg b/setup.cfg\nindex a9ab3befbf..4a29c7d490 100644\n--- a/setup.cfg\n+++ b/setup.cfg\n@@ -1,11 +1,26 @@\n+# Generated from:\n+# https://github.com/plone/meta/tree/master/config/default\n [zest.releaser]\n extra-message = [ci skip]\n \n [bdist_wheel]\n universal = 0\n \n-[isort]\n-profile = black\n-force_alphabetical_sort=True\n-force_single_line=True\n-lines_after_imports=2\n+[flake8]\n+doctests = 1\n+ignore =\n+ # black takes care of line length\n+ E501,\n+ # black takes care of where to break lines\n+ W503,\n+ # black takes care of spaces within slicing (list[:])\n+ E203,\n+ # black takes care of spaces after commas\n+ E231,\n+\n+[check-manifest]\n+ignore =\n+ .editorconfig\n+ .meta.toml\n+ .pre-commit-config.yaml\n+ tox.ini\ndiff --git a/tox.ini b/tox.ini\nnew file mode 100644\nindex 0000000000..20bdc5ed4b\n--- /dev/null\n+++ b/tox.ini\n@@ -0,0 +1,76 @@\n+# Generated from:\n+# https://github.com/plone/meta/tree/master/config/default\n+[tox]\n+# We need 4.4.0 for constrain_package_deps.\n+min_version = 4.4.0\n+envlist =\n+ format\n+ lint\n+ test\n+\n+[testenv]\n+allowlist_externals =\n+ sh\n+\n+[testenv:format]\n+description = automatically reformat code\n+skip_install = true\n+deps =\n+ pre-commit\n+commands =\n+ pre-commit run -a pyupgrade\n+ pre-commit run -a isort\n+ pre-commit run -a black\n+ pre-commit run -a zpretty\n+\n+[testenv:lint]\n+description = run linters that will help improve the code style\n+skip_install = true\n+deps =\n+ pre-commit\n+commands =\n+ pre-commit run -a\n+\n+[testenv:dependencies]\n+description = check if the package defines all its dependencies\n+skip_install = true\n+deps =\n+ build\n+ z3c.dependencychecker==2.11\n+commands =\n+ python -m build --sdist --no-isolation\n+ dependencychecker\n+\n+[testenv:dependencies-graph]\n+description = generate a graph out of the package\'s dependencies\n+deps =\n+ pipdeptree==2.5.1\n+ graphviz # optional dependency of pipdeptree\n+commands =\n+ sh -c \'pipdeptree --exclude setuptools,wheel,pipdeptree,zope.interface,zope.component --graph-output svg > dependencies.svg\'\n+\n+[testenv:test]\n+use_develop = true\n+constrain_package_deps = true\n+set_env = ROBOT_BROWSER=headlesschrome\n+deps =\n+ zope.testrunner\n+ -c https://dist.plone.org/release/6.0-dev/constraints.txt\n+commands =\n+ zope-testrunner --all --test-path={toxinidir} -s Products.CMFPlone {posargs}\n+extras =\n+ test\n+\n+[testenv:coverage]\n+use_develop = true\n+constrain_package_deps = true\n+set_env = ROBOT_BROWSER=headlesschrome\n+deps =\n+ coverage\n+ zope.testrunner\n+ -c https://dist.plone.org/release/6.0-dev/constraints.txt\n+commands =\n+ coverage run {envbindir}/zope-testrunner --quiet --all --test-path={toxinidir} -s Products.CMFPlone {posargs}\n+ coverage report -m --format markdown\n+extras =\n+ test\n'
-
-Repository: Products.CMFPlone
-
-
-Branch: refs/heads/6.0.x
-Date: 2023-05-17T00:25:46+02:00
-Author: Gil Forcada Codinachs (gforcada)
-Commit: https://github.com/plone/Products.CMFPlone/commit/6c0f4e194bf1ad221b44f5be196350870d34bcae
-
-chore: pyupgrade
-
-Files changed:
-M Products/CMFPlone/tests/test_redirect_after_login.py
-
-b'diff --git a/Products/CMFPlone/tests/test_redirect_after_login.py b/Products/CMFPlone/tests/test_redirect_after_login.py\nindex 4eb69b4a35..a5c8db9cac 100644\n--- a/Products/CMFPlone/tests/test_redirect_after_login.py\n+++ b/Products/CMFPlone/tests/test_redirect_after_login.py\n@@ -206,7 +206,7 @@ def test_password_reset_uses_all_adapters(self):\n # We need to configure the mailhost first.\n registry = getUtility(IRegistry, context=self.portal)\n mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n- mail_settings.smtp_host = u\'localhost\'\n+ mail_settings.smtp_host = \'localhost\'\n mail_settings.email_from_address = \'smith@example.com\'\n # and an email address for the test user:\n member = self.portal.portal_membership.getMemberById(TEST_USER_ID)\n@@ -230,7 +230,7 @@ def test_password_reset_uses_all_adapters(self):\n self.assertIn(please_visit_text, msg)\n url_index = msg.index(please_visit_text) + len(please_visit_text)\n address = msg[url_index:].strip().split()[0].decode()\n- self.assertTrue(address.startswith(u\'http://nohost/plone/passwordreset/\'))\n+ self.assertTrue(address.startswith(\'http://nohost/plone/passwordreset/\'))\n \n # Now that we have the address, we will reset our password:\n \n'
-
-Repository: Products.CMFPlone
-
-
-Branch: refs/heads/6.0.x
-Date: 2023-05-17T00:26:07+02:00
-Author: Gil Forcada Codinachs (gforcada)
-Commit: https://github.com/plone/Products.CMFPlone/commit/b4ca0a7dd5991bea8b012951410776230e5379a1
-
-chore: isort
-
-Files changed:
-M Products/CMFPlone/RegistrationTool.py
-M Products/CMFPlone/browser/contact_info.py
-M Products/CMFPlone/browser/login/login_help.py
-M Products/CMFPlone/browser/search.py
-
-b'diff --git a/Products/CMFPlone/RegistrationTool.py b/Products/CMFPlone/RegistrationTool.py\nindex b79cfc1ea4..1e2fc043c8 100644\n--- a/Products/CMFPlone/RegistrationTool.py\n+++ b/Products/CMFPlone/RegistrationTool.py\n@@ -33,6 +33,7 @@\n import random\n import re\n \n+\n try:\n # Products.MailHost has a patch to fix quoted-printable soft line breaks.\n # See https://github.com/zopefoundation/Products.MailHost/issues/35\ndiff --git a/Products/CMFPlone/browser/contact_info.py b/Products/CMFPlone/browser/contact_info.py\nindex c1cec8398c..dd38f91da0 100644\n--- a/Products/CMFPlone/browser/contact_info.py\n+++ b/Products/CMFPlone/browser/contact_info.py\n@@ -15,6 +15,7 @@\n import logging\n import warnings\n \n+\n try:\n # Products.MailHost has a patch to fix quoted-printable soft line breaks.\n # See https://github.com/zopefoundation/Products.MailHost/issues/35\ndiff --git a/Products/CMFPlone/browser/login/login_help.py b/Products/CMFPlone/browser/login/login_help.py\nindex c151141547..06f4170872 100644\n--- a/Products/CMFPlone/browser/login/login_help.py\n+++ b/Products/CMFPlone/browser/login/login_help.py\n@@ -21,6 +21,7 @@\n \n import logging\n \n+\n try:\n # Products.MailHost has a patch to fix quoted-printable soft line breaks.\n # See https://github.com/zopefoundation/Products.MailHost/issues/35\ndiff --git a/Products/CMFPlone/browser/search.py b/Products/CMFPlone/browser/search.py\nindex 902d052720..fa74d78782 100644\n--- a/Products/CMFPlone/browser/search.py\n+++ b/Products/CMFPlone/browser/search.py\n@@ -2,8 +2,8 @@\n from plone.app.contentlisting.interfaces import IContentListing\n from plone.app.layout.navigation.interfaces import INavigationRoot\n from plone.base.batch import Batch\n-from plone.base.interfaces.siteroot import IPloneSiteRoot\n from plone.base.interfaces import ISearchSchema\n+from plone.base.interfaces.siteroot import IPloneSiteRoot\n from plone.registry.interfaces import IRegistry\n from Products.CMFCore.utils import getToolByName\n from Products.CMFPlone.browser.navtree import getNavigationRoot\n'
-
-Repository: Products.CMFPlone
-
-
-Branch: refs/heads/6.0.x
-Date: 2023-05-17T00:27:37+02:00
-Author: Gil Forcada Codinachs (gforcada)
-Commit: https://github.com/plone/Products.CMFPlone/commit/bad7ee61597c72f165f5db979ee04efd06066d22
-
-chore: black
-
-Files changed:
-M Products/CMFPlone/ActionsTool.py
-M Products/CMFPlone/CatalogTool.py
-M Products/CMFPlone/MigrationTool.py
-M Products/CMFPlone/PasswordResetTool.py
-M Products/CMFPlone/PloneBatch.py
-M Products/CMFPlone/PloneControlPanel.py
-M Products/CMFPlone/PloneTool.py
-M Products/CMFPlone/Portal.py
-M Products/CMFPlone/PropertiesTool.py
-M Products/CMFPlone/RegistrationTool.py
-M Products/CMFPlone/SkinsTool.py
-M Products/CMFPlone/TranslationServiceTool.py
-M Products/CMFPlone/TypesTool.py
-M Products/CMFPlone/URLTool.py
-M Products/CMFPlone/UnicodeSplitter/config.py
-M Products/CMFPlone/UnicodeSplitter/splitter.py
-M Products/CMFPlone/WorkflowTool.py
-M Products/CMFPlone/__init__.py
-M Products/CMFPlone/bbb.py
-M Products/CMFPlone/browser/admin.py
-M Products/CMFPlone/browser/atd.py
-M Products/CMFPlone/browser/author.py
-M Products/CMFPlone/browser/contact_info.py
-M Products/CMFPlone/browser/defaultpage.py
-M Products/CMFPlone/browser/exceptions.py
-M Products/CMFPlone/browser/global_statusmessage.py
-M Products/CMFPlone/browser/icons.py
-M Products/CMFPlone/browser/interfaces.py
-M Products/CMFPlone/browser/login/login.py
-M Products/CMFPlone/browser/login/login_help.py
-M Products/CMFPlone/browser/login/logout.py
-M Products/CMFPlone/browser/login/mail_password.py
-M Products/CMFPlone/browser/login/password_reset.py
-M Products/CMFPlone/browser/login/utils.py
-M Products/CMFPlone/browser/main_template.py
-M Products/CMFPlone/browser/navtree.py
-M Products/CMFPlone/browser/okay.py
-M Products/CMFPlone/browser/ploneview.py
-M Products/CMFPlone/browser/robots.py
-M Products/CMFPlone/browser/search.py
-M Products/CMFPlone/browser/sendto.py
-M Products/CMFPlone/browser/sitelogo.py
-M Products/CMFPlone/browser/sitemap.py
-M Products/CMFPlone/browser/syndication/adapters.py
-M Products/CMFPlone/browser/syndication/settings.py
-M Products/CMFPlone/browser/syndication/tool.py
-M Products/CMFPlone/browser/syndication/utils.py
-M Products/CMFPlone/browser/syndication/views.py
-M Products/CMFPlone/browser/test_rendering.py
-M Products/CMFPlone/controlpanel/bbb/editing.py
-M Products/CMFPlone/controlpanel/bbb/filter.py
-M Products/CMFPlone/controlpanel/bbb/language.py
-M Products/CMFPlone/controlpanel/bbb/mail.py
-M Products/CMFPlone/controlpanel/bbb/maintenance.py
-M Products/CMFPlone/controlpanel/bbb/markup.py
-M Products/CMFPlone/controlpanel/bbb/navigation.py
-M Products/CMFPlone/controlpanel/bbb/search.py
-M Products/CMFPlone/controlpanel/bbb/security.py
-M Products/CMFPlone/controlpanel/bbb/site.py
-M Products/CMFPlone/controlpanel/bbb/usergroups.py
-M Products/CMFPlone/controlpanel/browser/actions.py
-M Products/CMFPlone/controlpanel/browser/dateandtime.py
-M Products/CMFPlone/controlpanel/browser/editing.py
-M Products/CMFPlone/controlpanel/browser/error_log_form.py
-M Products/CMFPlone/controlpanel/browser/filter.py
-M Products/CMFPlone/controlpanel/browser/imaging.py
-M Products/CMFPlone/controlpanel/browser/language.py
-M Products/CMFPlone/controlpanel/browser/mail.py
-M Products/CMFPlone/controlpanel/browser/maintenance.py
-M Products/CMFPlone/controlpanel/browser/markup.py
-M Products/CMFPlone/controlpanel/browser/navigation.py
-M Products/CMFPlone/controlpanel/browser/overview.py
-M Products/CMFPlone/controlpanel/browser/prefsmaintemplate.py
-M Products/CMFPlone/controlpanel/browser/quickinstaller.py
-M Products/CMFPlone/controlpanel/browser/redirects.py
-M Products/CMFPlone/controlpanel/browser/relations.py
-M Products/CMFPlone/controlpanel/browser/resourceregistry.py
-M Products/CMFPlone/controlpanel/browser/search.py
-M Products/CMFPlone/controlpanel/browser/security.py
-M Products/CMFPlone/controlpanel/browser/site.py
-M Products/CMFPlone/controlpanel/browser/socialmedia.py
-M Products/CMFPlone/controlpanel/browser/syndication.py
-M Products/CMFPlone/controlpanel/browser/tinymce.py
-M Products/CMFPlone/controlpanel/browser/types.py
-M Products/CMFPlone/controlpanel/browser/usergroups.py
-M Products/CMFPlone/controlpanel/browser/usergroups_groupdetails.py
-M Products/CMFPlone/controlpanel/browser/usergroups_groupmembership.py
-M Products/CMFPlone/controlpanel/browser/usergroups_groupsoverview.py
-M Products/CMFPlone/controlpanel/browser/usergroups_usermembership.py
-M Products/CMFPlone/controlpanel/browser/usergroups_usersoverview.py
-M Products/CMFPlone/controlpanel/events.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_actions.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_editing_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_filter_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_language_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_mail_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_maintenance_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_markup_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_navigation_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_search_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_security_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_site_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_usergroups_adapter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_editing.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_error_log.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_filter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_installer.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_language.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_mail.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_maintenance.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_markup.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_navigation.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_search.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_security.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_site.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_syndication.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_types.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups_siteadmin_role.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_dateandtime.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_doctest.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_editing.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_events.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_filter.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_installer.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_language.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_mail.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_markup.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_navigation.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_overview.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_relations.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_search.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_security.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_site.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_types.py
-M Products/CMFPlone/controlpanel/tests/test_controlpanel_usergroups.py
-M Products/CMFPlone/controlpanel/tests/test_doctests.py
-M Products/CMFPlone/controlpanel/utils.py
-M Products/CMFPlone/controlpanel/widgets.py
-M Products/CMFPlone/defaultpage.py
-M Products/CMFPlone/earlypatches/security.py
-M Products/CMFPlone/events.py
-M Products/CMFPlone/exportimport/controlpanel.py
-M Products/CMFPlone/exportimport/memberdata_properties.py
-M Products/CMFPlone/exportimport/propertiestool.py
-M Products/CMFPlone/exportimport/tests/base.py
-M Products/CMFPlone/exportimport/tests/testControlPanel.py
-M Products/CMFPlone/exportimport/tests/testPropertiesTool.py
-M Products/CMFPlone/factory.py
-M Products/CMFPlone/i18nl10n.py
-M Products/CMFPlone/interfaces/atd.py
-M Products/CMFPlone/interfaces/basetool.py
-M Products/CMFPlone/interfaces/breadcrumbs.py
-M Products/CMFPlone/interfaces/constrains.py
-M Products/CMFPlone/interfaces/controlpanel.py
-M Products/CMFPlone/interfaces/defaultpage.py
-M Products/CMFPlone/interfaces/events.py
-M Products/CMFPlone/interfaces/installable.py
-M Products/CMFPlone/interfaces/interface.py
-M Products/CMFPlone/interfaces/language.py
-M Products/CMFPlone/interfaces/login.py
-M Products/CMFPlone/interfaces/migration.py
-M Products/CMFPlone/interfaces/password_reset.py
-M Products/CMFPlone/interfaces/patterns.py
-M Products/CMFPlone/interfaces/properties.py
-M Products/CMFPlone/interfaces/resources.py
-M Products/CMFPlone/interfaces/siteroot.py
-M Products/CMFPlone/interfaces/structure.py
-M Products/CMFPlone/interfaces/syndication.py
-M Products/CMFPlone/interfaces/translationservice.py
-M Products/CMFPlone/interfaces/workflow.py
-M Products/CMFPlone/log.py
-M Products/CMFPlone/patches/__init__.py
-M Products/CMFPlone/patches/addzmiplonesite.py
-M Products/CMFPlone/patches/addzmisecuritywarning.py
-M Products/CMFPlone/patches/csrf.py
-M Products/CMFPlone/patches/dateIndexPatch.py
-M Products/CMFPlone/patches/gtbn.py
-M Products/CMFPlone/patches/iso8601.py
-M Products/CMFPlone/patches/publishing.py
-M Products/CMFPlone/patches/sendmail.py
-M Products/CMFPlone/patches/speed.py
-M Products/CMFPlone/patches/templatecookcheck.py
-M Products/CMFPlone/patches/unicodehacks.py
-M Products/CMFPlone/patches/z3c_form.py
-M Products/CMFPlone/permissions.py
-M Products/CMFPlone/relationhelper.py
-M Products/CMFPlone/resources/browser/resource.py
-M Products/CMFPlone/setuphandlers.py
-M Products/CMFPlone/skins/plone_scripts/externalEditorEnabled.py
-M Products/CMFPlone/skins/plone_scripts/external_edit.py
-M Products/CMFPlone/skins/plone_scripts/getFolderContents.py
-M Products/CMFPlone/skins/plone_scripts/pretty_title_or_id.py
-M Products/CMFPlone/skins/plone_scripts/queryCatalog.py
-M Products/CMFPlone/skins/plone_scripts/toLocalizedTime.py
-M Products/CMFPlone/skins/plone_scripts/translate.py
-M Products/CMFPlone/skins/plone_scripts/utranslate.py
-M Products/CMFPlone/testing.py
-M Products/CMFPlone/tests/PloneTestCase.py
-M Products/CMFPlone/tests/dummy.py
-M Products/CMFPlone/tests/robot/robot_setup.py
-M Products/CMFPlone/tests/testActionsTool.py
-M Products/CMFPlone/tests/testBatch.py
-M Products/CMFPlone/tests/testBrowserAdmin.py
-M Products/CMFPlone/tests/testBrowserDefault.py
-M Products/CMFPlone/tests/testBrowserLayerPrecedence.py
-M Products/CMFPlone/tests/testCSRFProtection.py
-M Products/CMFPlone/tests/testCatalogTool.py
-M Products/CMFPlone/tests/testCheckId.py
-M Products/CMFPlone/tests/testContentSecurity.py
-M Products/CMFPlone/tests/testControlPanel.py
-M Products/CMFPlone/tests/testControlPanelScripts.py
-M Products/CMFPlone/tests/testCookieAuth.py
-M Products/CMFPlone/tests/testCutPasteSecurity.py
-M Products/CMFPlone/tests/testDateIndexRanges.py
-M Products/CMFPlone/tests/testDateTimeIntegration.py
-M Products/CMFPlone/tests/testEmailLogin.py
-M Products/CMFPlone/tests/testExternalEditorEnabled.py
-M Products/CMFPlone/tests/testIImagingSchema.py
-M Products/CMFPlone/tests/testInterfaces.py
-M Products/CMFPlone/tests/testMigrationTool.py
-M Products/CMFPlone/tests/testNavTree.py
-M Products/CMFPlone/tests/testNavigationView.py
-M Products/CMFPlone/tests/testNextPrevious.py
-M Products/CMFPlone/tests/testOrderSupport.py
-M Products/CMFPlone/tests/testPloneTestCase.py
-M Products/CMFPlone/tests/testPloneView.py
-M Products/CMFPlone/tests/testPortalCreation.py
-M Products/CMFPlone/tests/testQueryCatalog.py
-M Products/CMFPlone/tests/testRegistrationTool.py
-M Products/CMFPlone/tests/testResourceRegistries.py
-M Products/CMFPlone/tests/testRestrictedAcquisition.py
-M Products/CMFPlone/tests/testSearch.py
-M Products/CMFPlone/tests/testSecurity.py
-M Products/CMFPlone/tests/testSecurityDeclarations.py
-M Products/CMFPlone/tests/testSiteAdminRole.py
-M Products/CMFPlone/tests/testSyndication.py
-M Products/CMFPlone/tests/testTranslationServiceTool.py
-M Products/CMFPlone/tests/testURLTool.py
-M Products/CMFPlone/tests/testUnicodeSplitter.py
-M Products/CMFPlone/tests/testUserFolderBasics.py
-M Products/CMFPlone/tests/testWebDAV.py
-M Products/CMFPlone/tests/testWorkflowTool.py
-M Products/CMFPlone/tests/test_PloneTool.py
-M Products/CMFPlone/tests/test_defaultpage.py
-M Products/CMFPlone/tests/test_doctests.py
-M Products/CMFPlone/tests/test_error_message.py
-M Products/CMFPlone/tests/test_expressions.py
-M Products/CMFPlone/tests/test_factory.py
-M Products/CMFPlone/tests/test_functional.py
-M Products/CMFPlone/tests/test_icons.py
-M Products/CMFPlone/tests/test_login_form.py
-M Products/CMFPlone/tests/test_login_help.py
-M Products/CMFPlone/tests/test_login_logout.py
-M Products/CMFPlone/tests/test_login_views.py
-M Products/CMFPlone/tests/test_mails.py
-M Products/CMFPlone/tests/test_nogopip.py
-M Products/CMFPlone/tests/test_okay.py
-M Products/CMFPlone/tests/test_passwordreset.py
-M Products/CMFPlone/tests/test_patternsettings.py
-M Products/CMFPlone/tests/test_redirect_after_login.py
-M Products/CMFPlone/tests/test_robot.py
-M Products/CMFPlone/tests/test_robots_txt.py
-M Products/CMFPlone/tests/test_safe_formatter.py
-M Products/CMFPlone/tests/test_sitelogo.py
-M Products/CMFPlone/tests/test_sitemap.py
-M Products/CMFPlone/tests/test_utils.py
-M Products/CMFPlone/tests/test_z3c_form_widgets.py
-M Products/CMFPlone/tests/test_zmi.py
-M Products/CMFPlone/tests/utils.py
-M Products/CMFPlone/unicodeconflictresolver.py
-M Products/CMFPlone/utils.py
-M Products/CMFPlone/workflow.py
-M Products/__init__.py
-M setup.py
-
-b'diff --git a/Products/CMFPlone/ActionsTool.py b/Products/CMFPlone/ActionsTool.py\nindex 5ae39fb5f0..e0c01f8d8d 100644\n--- a/Products/CMFPlone/ActionsTool.py\n+++ b/Products/CMFPlone/ActionsTool.py\n@@ -8,7 +8,6 @@\n \n \n class ActionsTool(PloneBaseTool, BaseTool):\n-\n meta_type = "Plone Actions Tool"\n toolicon = "skins/plone_images/confirm_icon.png"\n \ndiff --git a/Products/CMFPlone/CatalogTool.py b/Products/CMFPlone/CatalogTool.py\nindex c83320dc07..0e07a2fb72 100644\n--- a/Products/CMFPlone/CatalogTool.py\n+++ b/Products/CMFPlone/CatalogTool.py\n@@ -1,7 +1,9 @@\n from AccessControl import ClassSecurityInfo\n from AccessControl.class_init import InitializeClass\n from AccessControl.PermissionRole import rolesForPermissionOn\n-from AccessControl.Permissions import manage_zcatalog_entries as ManageZCatalogEntries # noqa\n+from AccessControl.Permissions import (\n+ manage_zcatalog_entries as ManageZCatalogEntries,\n+) # noqa\n from AccessControl.Permissions import search_zcatalog as SearchZCatalog\n from Acquisition import aq_base\n from Acquisition import aq_inner\n@@ -45,70 +47,72 @@\n import urllib\n \n \n-logger = logging.getLogger(\'Plone\')\n+logger = logging.getLogger("Plone")\n \n _marker = object()\n \n-DENIED_INTERFACES = frozenset((\n- \'AccessControl.interfaces.IOwned\',\n- \'AccessControl.interfaces.IPermissionMappingSupport\',\n- \'AccessControl.interfaces.IRoleManager\',\n- \'Acquisition.interfaces.IAcquirer\',\n- \'App.interfaces.INavigation\',\n- \'App.interfaces.IPersistentExtra\',\n- \'App.interfaces.IUndoSupport\',\n- \'OFS.interfaces.ICopyContainer\',\n- \'OFS.interfaces.ICopySource\',\n- \'OFS.interfaces.IFindSupport\',\n- \'OFS.interfaces.IFolder\',\n- \'OFS.interfaces.IFTPAccess\',\n- \'OFS.interfaces.IItem\',\n- \'OFS.interfaces.IManageable\',\n- \'OFS.interfaces.IObjectManager\',\n- \'OFS.interfaces.IOrderedContainer\',\n- \'OFS.interfaces.IPropertyManager\',\n- \'OFS.interfaces.ISimpleItem\',\n- \'OFS.interfaces.ITraversable\',\n- \'OFS.interfaces.IZopeObject\',\n- \'persistent.interfaces.IPersistent\',\n- \'plone.app.iterate.interfaces.IIterateAware\',\n- \'plone.contentrules.engine.interfaces.IRuleAssignable\',\n- \'plone.folder.interfaces.IFolder\',\n- \'plone.folder.interfaces.IOrderableFolder\',\n- \'plone.locking.interfaces.ITTWLockable\',\n- \'plone.portlets.interfaces.ILocalPortletAssignable\',\n- \'plone.uuid.interfaces.IUUIDAware\',\n- \'Products.CMFCore.interfaces._content.ICatalogableDublinCore\',\n- \'Products.CMFCore.interfaces._content.ICatalogAware\',\n- \'Products.CMFCore.interfaces._content.IDublinCore\',\n- \'Products.CMFCore.interfaces._content.IDynamicType\',\n- \'Products.CMFCore.interfaces._content.IFolderish\',\n- \'Products.CMFCore.interfaces._content.IMinimalDublinCore\',\n- \'Products.CMFCore.interfaces._content.IMutableDublinCore\',\n- \'Products.CMFCore.interfaces._content.IMutableMinimalDublinCore\',\n- \'Products.CMFCore.interfaces._content.IOpaqueItemManager\',\n- \'Products.CMFCore.interfaces._content.IWorkflowAware\',\n- \'Products.CMFDynamicViewFTI.interfaces.IBrowserDefault\',\n- \'Products.CMFDynamicViewFTI.interfaces.ISelectableBrowserDefault\',\n- \'plone.base.interfaces.constrains.IConstrainTypes\',\n- \'plone.base.interfaces.constrains.ISelectableConstrainTypes\',\n- \'Products.GenericSetup.interfaces.IDAVAware\',\n- \'webdav.EtagSupport.EtagBaseInterface\',\n- \'webdav.interfaces.IDAVCollection\',\n- \'webdav.interfaces.IDAVResource\',\n- \'zope.annotation.interfaces.IAnnotatable\',\n- \'zope.annotation.interfaces.IAttributeAnnotatable\',\n- \'zope.component.interfaces.IPossibleSite\',\n- \'zope.container.interfaces.IContainer\',\n- \'zope.container.interfaces.IItemContainer\',\n- \'zope.container.interfaces.IReadContainer\',\n- \'zope.container.interfaces.ISimpleReadContainer\',\n- \'zope.container.interfaces.IWriteContainer\',\n- \'zope.interface.common.mapping.IEnumerableMapping\',\n- \'zope.interface.common.mapping.IItemMapping\',\n- \'zope.interface.common.mapping.IReadMapping\',\n- \'zope.interface.Interface\',\n-))\n+DENIED_INTERFACES = frozenset(\n+ (\n+ "AccessControl.interfaces.IOwned",\n+ "AccessControl.interfaces.IPermissionMappingSupport",\n+ "AccessControl.interfaces.IRoleManager",\n+ "Acquisition.interfaces.IAcquirer",\n+ "App.interfaces.INavigation",\n+ "App.interfaces.IPersistentExtra",\n+ "App.interfaces.IUndoSupport",\n+ "OFS.interfaces.ICopyContainer",\n+ "OFS.interfaces.ICopySource",\n+ "OFS.interfaces.IFindSupport",\n+ "OFS.interfaces.IFolder",\n+ "OFS.interfaces.IFTPAccess",\n+ "OFS.interfaces.IItem",\n+ "OFS.interfaces.IManageable",\n+ "OFS.interfaces.IObjectManager",\n+ "OFS.interfaces.IOrderedContainer",\n+ "OFS.interfaces.IPropertyManager",\n+ "OFS.interfaces.ISimpleItem",\n+ "OFS.interfaces.ITraversable",\n+ "OFS.interfaces.IZopeObject",\n+ "persistent.interfaces.IPersistent",\n+ "plone.app.iterate.interfaces.IIterateAware",\n+ "plone.contentrules.engine.interfaces.IRuleAssignable",\n+ "plone.folder.interfaces.IFolder",\n+ "plone.folder.interfaces.IOrderableFolder",\n+ "plone.locking.interfaces.ITTWLockable",\n+ "plone.portlets.interfaces.ILocalPortletAssignable",\n+ "plone.uuid.interfaces.IUUIDAware",\n+ "Products.CMFCore.interfaces._content.ICatalogableDublinCore",\n+ "Products.CMFCore.interfaces._content.ICatalogAware",\n+ "Products.CMFCore.interfaces._content.IDublinCore",\n+ "Products.CMFCore.interfaces._content.IDynamicType",\n+ "Products.CMFCore.interfaces._content.IFolderish",\n+ "Products.CMFCore.interfaces._content.IMinimalDublinCore",\n+ "Products.CMFCore.interfaces._content.IMutableDublinCore",\n+ "Products.CMFCore.interfaces._content.IMutableMinimalDublinCore",\n+ "Products.CMFCore.interfaces._content.IOpaqueItemManager",\n+ "Products.CMFCore.interfaces._content.IWorkflowAware",\n+ "Products.CMFDynamicViewFTI.interfaces.IBrowserDefault",\n+ "Products.CMFDynamicViewFTI.interfaces.ISelectableBrowserDefault",\n+ "plone.base.interfaces.constrains.IConstrainTypes",\n+ "plone.base.interfaces.constrains.ISelectableConstrainTypes",\n+ "Products.GenericSetup.interfaces.IDAVAware",\n+ "webdav.EtagSupport.EtagBaseInterface",\n+ "webdav.interfaces.IDAVCollection",\n+ "webdav.interfaces.IDAVResource",\n+ "zope.annotation.interfaces.IAnnotatable",\n+ "zope.annotation.interfaces.IAttributeAnnotatable",\n+ "zope.component.interfaces.IPossibleSite",\n+ "zope.container.interfaces.IContainer",\n+ "zope.container.interfaces.IItemContainer",\n+ "zope.container.interfaces.IReadContainer",\n+ "zope.container.interfaces.ISimpleReadContainer",\n+ "zope.container.interfaces.IWriteContainer",\n+ "zope.interface.common.mapping.IEnumerableMapping",\n+ "zope.interface.common.mapping.IItemMapping",\n+ "zope.interface.common.mapping.IReadMapping",\n+ "zope.interface.Interface",\n+ )\n+)\n \n # bbb, remove in Plone 7\n BLACKLISTED_INTERFACES = DENIED_INTERFACES\n@@ -123,48 +127,49 @@ def allowedRolesAndUsers(obj):\n # \'Access contents information\' is the correct permission for\n # accessing and displaying metadata of an item.\n # \'View\' should be reserved for accessing the item itself.\n- allowed = set(rolesForPermissionOn(\'Access contents information\', obj))\n+ allowed = set(rolesForPermissionOn("Access contents information", obj))\n \n # shortcut roles and only index the most basic system role if the object\n # is viewable by either of those\n- if \'Anonymous\' in allowed:\n- return [\'Anonymous\']\n- elif \'Authenticated\' in allowed:\n- return [\'Authenticated\']\n+ if "Anonymous" in allowed:\n+ return ["Anonymous"]\n+ elif "Authenticated" in allowed:\n+ return ["Authenticated"]\n localroles = {}\n try:\n- acl_users = getToolByName(obj, \'acl_users\', None)\n+ acl_users = getToolByName(obj, "acl_users", None)\n if acl_users is not None:\n localroles = acl_users._getAllLocalRoles(obj)\n except AttributeError:\n localroles = _mergedLocalRoles(obj)\n for user, roles in localroles.items():\n if allowed.intersection(roles):\n- allowed.update([\'user:\' + user])\n- if \'Owner\' in allowed:\n- allowed.remove(\'Owner\')\n+ allowed.update(["user:" + user])\n+ if "Owner" in allowed:\n+ allowed.remove("Owner")\n return list(allowed)\n \n \n @indexer(Interface)\n def object_provides(obj):\n return tuple(\n- i.__identifier__ for i in providedBy(obj).flattened()\n- if i.__identifier__ not in DENIED_INTERFACES\n+ i.__identifier__\n+ for i in providedBy(obj).flattened()\n+ if i.__identifier__ not in DENIED_INTERFACES\n )\n \n \n def zero_fill(matchobj):\n return matchobj.group().zfill(4)\n \n-num_sort_regex = re.compile(r\'\\d+\')\n+\n+num_sort_regex = re.compile(r"\\d+")\n \n \n @indexer(Interface)\n def sortable_title(obj):\n- """ Helper method for to provide FieldIndex for Title.\n- """\n- title = getattr(obj, \'Title\', None)\n+ """Helper method for to provide FieldIndex for Title."""\n+ title = getattr(obj, "Title", None)\n if title is not None:\n if safe_callable(title):\n title = title()\n@@ -175,13 +180,12 @@ def sortable_title(obj):\n # Replace numbers with zero filled numbers\n sortabletitle = num_sort_regex.sub(zero_fill, sortabletitle)\n return sortabletitle\n- return \'\'\n+ return ""\n \n \n @indexer(Interface)\n def getObjPositionInParent(obj):\n- """ Helper method for catalog based folder contents.\n- """\n+ """Helper method for catalog based folder contents."""\n parent = aq_parent(aq_inner(obj))\n ordered = IOrderedContainer(parent, None)\n if ordered is not None:\n@@ -191,9 +195,8 @@ def getObjPositionInParent(obj):\n \n @indexer(Interface)\n def getObjSize(obj):\n- """ Helper method for catalog based folder contents.\n- """\n- if base_hasattr(obj, \'get_size\'):\n+ """Helper method for catalog based folder contents."""\n+ if base_hasattr(obj, "get_size"):\n size = obj.get_size()\n else:\n size = 0\n@@ -210,15 +213,14 @@ def is_folderish(obj):\n """\n # If the object explicitly states it doesn\'t want to be treated as a\n # structural folder, don\'t argue with it.\n- folderish = bool(getattr(aq_base(obj), \'isPrincipiaFolderish\', False))\n+ folderish = bool(getattr(aq_base(obj), "isPrincipiaFolderish", False))\n return folderish and not INonStructuralFolder.providedBy(obj)\n \n \n @indexer(Interface)\n def is_default_page(obj):\n- """Is this the default page in its folder\n- """\n- ptool = getToolByName(obj, \'plone_utils\', None)\n+ """Is this the default page in its folder"""\n+ ptool = getToolByName(obj, "plone_utils", None)\n if ptool is None:\n return False\n return ptool.isDefaultPage(obj)\n@@ -235,7 +237,7 @@ def getIcon(obj):\n when obj is an image or has a lead image\n or has an image field with name \'image\': true else false\n """\n- return bool(getattr(obj.aq_base, \'image\', False))\n+ return bool(getattr(obj.aq_base, "image", False))\n \n \n @indexer(Interface)\n@@ -247,22 +249,22 @@ def mime_type(obj):\n class CatalogTool(PloneBaseTool, BaseTool):\n """Plone\'s catalog tool"""\n \n- meta_type = \'Plone Catalog Tool\'\n+ meta_type = "Plone Catalog Tool"\n security = ClassSecurityInfo()\n- toolicon = \'skins/plone_images/book_icon.png\'\n+ toolicon = "skins/plone_images/book_icon.png"\n _counter = None\n \n- manage_catalogAdvanced = DTMLFile(\'www/catalogAdvanced\', globals())\n+ manage_catalogAdvanced = DTMLFile("www/catalogAdvanced", globals())\n \n manage_options = (\n- {\'action\': \'manage_main\', \'label\': \'Contents\'},\n- {\'action\': \'manage_catalogView\', \'label\': \'Catalog\'},\n- {\'action\': \'manage_catalogIndexes\', \'label\': \'Indexes\'},\n- {\'action\': \'manage_catalogSchema\', \'label\': \'Metadata\'},\n- {\'action\': \'manage_catalogAdvanced\', \'label\': \'Advanced\'},\n- {\'action\': \'manage_catalogReport\', \'label\': \'Query Report\'},\n- {\'action\': \'manage_catalogPlan\', \'label\': \'Query Plan\'},\n- {\'action\': \'manage_propertiesForm\', \'label\': \'Properties\'},\n+ {"action": "manage_main", "label": "Contents"},\n+ {"action": "manage_catalogView", "label": "Catalog"},\n+ {"action": "manage_catalogIndexes", "label": "Indexes"},\n+ {"action": "manage_catalogSchema", "label": "Metadata"},\n+ {"action": "manage_catalogAdvanced", "label": "Advanced"},\n+ {"action": "manage_catalogReport", "label": "Query Report"},\n+ {"action": "manage_catalogPlan", "label": "Query Plan"},\n+ {"action": "manage_propertiesForm", "label": "Properties"},\n )\n \n def __init__(self):\n@@ -278,17 +280,17 @@ def _removeIndex(self, index):\n def _listAllowedRolesAndUsers(self, user):\n # Makes sure the list includes the user\'s groups.\n result = user.getRoles()\n- if \'Anonymous\' in result:\n+ if "Anonymous" in result:\n # The anonymous user has no further roles\n- return [\'Anonymous\']\n+ return ["Anonymous"]\n result = list(result)\n- if hasattr(aq_base(user), \'getGroups\'):\n- groups = [\'user:%s\' % x for x in user.getGroups()]\n+ if hasattr(aq_base(user), "getGroups"):\n+ groups = ["user:%s" % x for x in user.getGroups()]\n if groups:\n result = result + groups\n # Order the arguments from small to large sets\n- result.insert(0, \'user:%s\' % user.getId())\n- result.append(\'Anonymous\')\n+ result.insert(0, "user:%s" % user.getId())\n+ result.append("Anonymous")\n return result\n \n @security.private\n@@ -301,8 +303,9 @@ def indexObject(self, object, idxs=None):\n self.reindexObject(object, idxs)\n \n @security.protected(ManageZCatalogEntries)\n- def catalog_object(self, object, uid=None, idxs=None,\n- update_metadata=1, pghandler=None):\n+ def catalog_object(\n+ self, object, uid=None, idxs=None, update_metadata=1, pghandler=None\n+ ):\n if idxs is None:\n idxs = []\n self._increment_counter()\n@@ -315,8 +318,9 @@ def catalog_object(self, object, uid=None, idxs=None,\n if wrapper is not None:\n w = wrapper\n \n- ZCatalog.catalog_object(self, w, uid, idxs,\n- update_metadata, pghandler=pghandler)\n+ ZCatalog.catalog_object(\n+ self, w, uid, idxs, update_metadata, pghandler=pghandler\n+ )\n \n @security.protected(ManageZCatalogEntries)\n def uncatalog_object(self, *args, **kwargs):\n@@ -346,14 +350,14 @@ def allow_inactive(self, query_kw):\n if allow_inactive:\n return True\n \n- paths = query_kw.get(\'path\', False)\n+ paths = query_kw.get("path", False)\n if not paths:\n return False\n \n if isinstance(paths, dict):\n # Like: {\'path\': {\'depth\': 0, \'query\': [\'/Plone/events/\']}}\n # Or: {\'path\': {\'depth\': 0, \'query\': \'/Plone/events/\'}}\n- paths = paths.get(\'query\', [])\n+ paths = paths.get("query", [])\n \n if isinstance(paths, str):\n paths = [paths]\n@@ -362,9 +366,9 @@ def allow_inactive(self, query_kw):\n site = getSite()\n for path in list(paths):\n try:\n- site_path = \'/\'.join(site.getPhysicalPath())\n- parts = path[len(site_path) + 1:].split(\'/\')\n- parent = site.unrestrictedTraverse(\'/\'.join(parts[:-1]))\n+ site_path = "/".join(site.getPhysicalPath())\n+ parts = path[len(site_path) + 1 :].split("/")\n+ parent = site.unrestrictedTraverse("/".join(parts[:-1]))\n objs.append(parent.restrictedTraverse(parts[-1]))\n except (KeyError, AttributeError, Unauthorized):\n # When no object is found don\'t raise an error\n@@ -375,8 +379,7 @@ def allow_inactive(self, query_kw):\n \n allow = True\n for ob in objs:\n- allow = allow and\\\n- _checkPermission(AccessInactivePortalContent, ob)\n+ allow = allow and _checkPermission(AccessInactivePortalContent, ob)\n \n return allow\n \n@@ -395,18 +398,18 @@ def searchResults(self, query=None, **kw):\n processQueue()\n \n kw = kw.copy()\n- show_inactive = kw.get(\'show_inactive\', False)\n+ show_inactive = kw.get("show_inactive", False)\n if isinstance(query, dict) and not show_inactive:\n- show_inactive = \'show_inactive\' in query\n+ show_inactive = "show_inactive" in query\n \n user = _getAuthenticatedUser(self)\n- kw[\'allowedRolesAndUsers\'] = self._listAllowedRolesAndUsers(user)\n+ kw["allowedRolesAndUsers"] = self._listAllowedRolesAndUsers(user)\n \n if not show_inactive and not self.allow_inactive(kw):\n- kw[\'effectiveRange\'] = DateTime()\n+ kw["effectiveRange"] = DateTime()\n \n # filter out invalid sort_on indexes\n- sort_on = kw.get(\'sort_on\') or []\n+ sort_on = kw.get("sort_on") or []\n if isinstance(sort_on, str):\n sort_on = [sort_on]\n valid_indexes = self.indexes()\n@@ -416,29 +419,27 @@ def searchResults(self, query=None, **kw):\n # sort_on is not iterable\n sort_on = []\n if not sort_on:\n- kw.pop(\'sort_on\', None)\n+ kw.pop("sort_on", None)\n else:\n- kw[\'sort_on\'] = sort_on\n+ kw["sort_on"] = sort_on\n \n return ZCatalog.searchResults(self, query, **kw)\n \n __call__ = searchResults\n \n- def search(self, query,\n- sort_index=None, reverse=0, limit=None, merge=1):\n+ def search(self, query, sort_index=None, reverse=0, limit=None, merge=1):\n # Wrap search() the same way that searchResults() is\n \n # Make sure any pending index tasks have been processed\n processQueue()\n \n user = _getAuthenticatedUser(self)\n- query[\'allowedRolesAndUsers\'] = self._listAllowedRolesAndUsers(user)\n+ query["allowedRolesAndUsers"] = self._listAllowedRolesAndUsers(user)\n \n if not self.allow_inactive(query):\n- query[\'effectiveRange\'] = DateTime()\n+ query["effectiveRange"] = DateTime()\n \n- return super().search(\n- query, sort_index, reverse, limit, merge)\n+ return super().search(query, sort_index, reverse, limit, merge)\n \n @security.protected(ManageZCatalogEntries)\n def clearFindAndRebuild(self):\n@@ -450,7 +451,7 @@ def clearFindAndRebuild(self):\n def indexObject(obj, path):\n if (\n obj != self\n- and base_hasattr(obj, \'reindexObject\')\n+ and base_hasattr(obj, "reindexObject")\n and safe_callable(obj.reindexObject)\n ):\n try:\n@@ -469,14 +470,11 @@ def indexObject(obj, path):\n # Catalogs have \'indexObject\' as well, but they\n # take different args, and will fail\n pass\n+\n self.manage_catalogClear()\n portal = aq_parent(aq_inner(self))\n- indexObject(portal, \'\')\n- portal.ZopeFindAndApply(\n- portal,\n- search_sub=True,\n- apply_func=indexObject\n- )\n+ indexObject(portal, "")\n+ portal.ZopeFindAndApply(portal, search_sub=True, apply_func=indexObject)\n \n @security.protected(ManageZCatalogEntries)\n def manage_catalogRebuild(self, RESPONSE=None, URL1=None):\n@@ -491,14 +489,19 @@ def manage_catalogRebuild(self, RESPONSE=None, URL1=None):\n elapse = time.time() - elapse\n c_elapse = process_time() - c_elapse\n \n- msg = (\'Catalog Rebuilt\\n\'\n- \'Total time: %s\\n\'\n- \'Total CPU time: %s\' % (repr(elapse), repr(c_elapse)))\n+ msg = (\n+ "Catalog Rebuilt\\n"\n+ "Total time: %s\\n"\n+ "Total CPU time: %s" % (repr(elapse), repr(c_elapse))\n+ )\n logger.info(msg)\n \n if RESPONSE is not None:\n RESPONSE.redirect(\n- URL1 + \'/manage_catalogAdvanced?manage_tabs_message=\' +\n- urllib.parse.quote(msg))\n+ URL1\n+ + "/manage_catalogAdvanced?manage_tabs_message="\n+ + urllib.parse.quote(msg)\n+ )\n+\n \n InitializeClass(CatalogTool)\ndiff --git a/Products/CMFPlone/MigrationTool.py b/Products/CMFPlone/MigrationTool.py\nindex 98285bd0c8..aefc10f3ac 100644\n--- a/Products/CMFPlone/MigrationTool.py\n+++ b/Products/CMFPlone/MigrationTool.py\n@@ -20,7 +20,7 @@\n import transaction\n \n \n-logger = logging.getLogger(\'plone.app.upgrade\')\n+logger = logging.getLogger("plone.app.upgrade")\n _upgradePaths = {}\n \n \n@@ -46,8 +46,7 @@ def __init__(self, profile_id=None, check_module=None):\n self.check_module = check_module\n \n def __repr__(self):\n- return \'<{} profile {}>\'.format(\n- self.__class__.__name__, self.profile_id)\n+ return "<{} profile {}>".format(self.__class__.__name__, self.profile_id)\n \n def safe(self):\n # Is this addon safe to upgrade?\n@@ -68,16 +67,16 @@ def safe(self):\n try:\n __import__(self.check_module)\n except ImportError:\n- logger.info(\'Cannot import module %s. Ignoring %s\',\n- self.check_module, self)\n+ logger.info(\n+ "Cannot import module %s. Ignoring %s", self.check_module, self\n+ )\n return False\n return True\n \n \n class AddonList(list):\n-\n def upgrade_all(self, context):\n- setup = getToolByName(context, \'portal_setup\')\n+ setup = getToolByName(context, "portal_setup")\n for addon in self:\n if addon.safe():\n setup.upgradeProfile(addon.profile_id, quiet=True)\n@@ -88,153 +87,144 @@ def upgrade_all(self, context):\n # Good start is portal_setup.listProfilesWithUpgrades()\n # Please use \'check_module\' for packages that are not direct dependencies\n # of Products.CMFPlone, but of the Plone package.\n-ADDON_LIST = AddonList([\n- Addon(profile_id=\'Products.CMFEditions:CMFEditions\'),\n- Addon(\n- profile_id=\'Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow\',\n- check_module=\'Products.CMFPlacefulWorkflow\'\n- ),\n- Addon(profile_id=\'Products.PlonePAS:PlonePAS\'),\n- Addon(\n- profile_id=\'plone.app.caching:default\',\n- check_module=\'plone.app.caching\'\n- ),\n- Addon(profile_id=\'plone.app.contenttypes:default\'),\n- Addon(profile_id=\'plone.app.dexterity:default\'),\n- Addon(profile_id=\'plone.app.discussion:default\'),\n- Addon(profile_id=\'plone.app.event:default\'),\n- Addon(\n- profile_id=\'plone.app.iterate:default\',\n- check_module=\'plone.app.iterate\'\n- ),\n- Addon(profile_id=\'plone.app.multilingual:default\'),\n- Addon(profile_id=\'plone.app.querystring:default\'),\n- Addon(profile_id=\'plone.app.theming:default\'),\n- Addon(profile_id=\'plone.app.users:default\'),\n- Addon(\n- profile_id=\'plone.restapi:default\',\n- check_module=\'plone.restapi\'\n- ),\n- Addon(profile_id=\'plone.session:default\'),\n- Addon(profile_id=\'plone.staticresources:default\'),\n- Addon(\n- profile_id=\'plone.volto:default\',\n- check_module=\'plone.volto\'\n- ),\n- Addon(profile_id=\'plonetheme.barceloneta:default\'),\n-])\n+ADDON_LIST = AddonList(\n+ [\n+ Addon(profile_id="Products.CMFEditions:CMFEditions"),\n+ Addon(\n+ profile_id="Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow",\n+ check_module="Products.CMFPlacefulWorkflow",\n+ ),\n+ Addon(profile_id="Products.PlonePAS:PlonePAS"),\n+ Addon(profile_id="plone.app.caching:default", check_module="plone.app.caching"),\n+ Addon(profile_id="plone.app.contenttypes:default"),\n+ Addon(profile_id="plone.app.dexterity:default"),\n+ Addon(profile_id="plone.app.discussion:default"),\n+ Addon(profile_id="plone.app.event:default"),\n+ Addon(profile_id="plone.app.iterate:default", check_module="plone.app.iterate"),\n+ Addon(profile_id="plone.app.multilingual:default"),\n+ Addon(profile_id="plone.app.querystring:default"),\n+ Addon(profile_id="plone.app.theming:default"),\n+ Addon(profile_id="plone.app.users:default"),\n+ Addon(profile_id="plone.restapi:default", check_module="plone.restapi"),\n+ Addon(profile_id="plone.session:default"),\n+ Addon(profile_id="plone.staticresources:default"),\n+ Addon(profile_id="plone.volto:default", check_module="plone.volto"),\n+ Addon(profile_id="plonetheme.barceloneta:default"),\n+ ]\n+)\n \n \n @implementer(IMigrationTool)\n class MigrationTool(PloneBaseTool, UniqueObject, SimpleItem):\n """Handles migrations between Plone releases"""\n \n- id = \'portal_migration\'\n- meta_type = \'Plone Migration Tool\'\n- toolicon = \'skins/plone_images/site_icon.png\'\n+ id = "portal_migration"\n+ meta_type = "Plone Migration Tool"\n+ toolicon = "skins/plone_images/site_icon.png"\n \n manage_options = (\n- ({\'label\': \'Upgrade\', \'action\': \'../@@plone-upgrade\'}, ) +\n- SimpleItem.manage_options)\n+ {"label": "Upgrade", "action": "../@@plone-upgrade"},\n+ ) + SimpleItem.manage_options\n \n _needRecatalog = 0\n _needUpdateRole = 0\n \n security = ClassSecurityInfo()\n \n- security.declareProtected(ManagePortal, \'getInstanceVersion\')\n+ security.declareProtected(ManagePortal, "getInstanceVersion")\n \n def getInstanceVersion(self):\n # The version this instance of plone is on.\n- setup = getToolByName(self, \'portal_setup\')\n+ setup = getToolByName(self, "portal_setup")\n version = setup.getLastVersionForProfile(_DEFAULT_PROFILE)\n if isinstance(version, tuple):\n- version = \'.\'.join(version)\n+ version = ".".join(version)\n \n- _version = getattr(self, \'_version\', None)\n+ _version = getattr(self, "_version", None)\n if _version is None:\n self._version = False\n \n- if version == \'unknown\':\n+ if version == "unknown":\n if _version:\n # Instance version was not pkg_resources compatible...\n- _version = _version.replace(\'devel (svn/unreleased)\', \'dev\')\n- _version = _version.rstrip(\'-final\')\n- _version = _version.rstrip(\'final\')\n- _version = _version.replace(\'alpha\', \'a\')\n- _version = _version.replace(\'beta\', \'b\')\n- _version = _version.replace(\'-\', \'.\')\n+ _version = _version.replace("devel (svn/unreleased)", "dev")\n+ _version = _version.rstrip("-final")\n+ _version = _version.rstrip("final")\n+ _version = _version.replace("alpha", "a")\n+ _version = _version.replace("beta", "b")\n+ _version = _version.replace("-", ".")\n version = _version\n else:\n version = setup.getVersionForProfile(_DEFAULT_PROFILE)\n self.setInstanceVersion(version)\n return version\n \n- security.declareProtected(ManagePortal, \'setInstanceVersion\')\n+ security.declareProtected(ManagePortal, "setInstanceVersion")\n \n def setInstanceVersion(self, version):\n # The version this instance of plone is on.\n- setup = getToolByName(self, \'portal_setup\')\n+ setup = getToolByName(self, "portal_setup")\n setup.setLastVersionForProfile(_DEFAULT_PROFILE, version)\n self._version = False\n \n- security.declareProtected(ManagePortal, \'getFileSystemVersion\')\n+ security.declareProtected(ManagePortal, "getFileSystemVersion")\n \n def getFileSystemVersion(self):\n # The version this instance of plone is on.\n- setup = getToolByName(self, \'portal_setup\')\n+ setup = getToolByName(self, "portal_setup")\n try:\n return setup.getVersionForProfile(_DEFAULT_PROFILE)\n except KeyError:\n pass\n return None\n \n- security.declareProtected(ManagePortal, \'getSoftwareVersion\')\n+ security.declareProtected(ManagePortal, "getSoftwareVersion")\n \n def getSoftwareVersion(self):\n # The software version.\n- dist = pkg_resources.get_distribution(\'Products.CMFPlone\')\n+ dist = pkg_resources.get_distribution("Products.CMFPlone")\n return dist.version\n \n- security.declareProtected(ManagePortal, \'needUpgrading\')\n+ security.declareProtected(ManagePortal, "needUpgrading")\n \n def needUpgrading(self):\n # Need upgrading?\n return self.getInstanceVersion() != self.getFileSystemVersion()\n \n- security.declareProtected(ManagePortal, \'coreVersions\')\n+ security.declareProtected(ManagePortal, "coreVersions")\n \n def coreVersions(self):\n # Useful core information.\n vars = {}\n get_dist = pkg_resources.get_distribution\n- vars[\'Zope\'] = get_dist(\'Zope\').version\n- vars[\'Python\'] = sys.version\n- vars[\'Platform\'] = sys.platform\n- vars[\'Plone\'] = get_dist(\'Products.CMFPlone\').version\n- vars[\'Plone Instance\'] = self.getInstanceVersion()\n- vars[\'Plone File System\'] = self.getFileSystemVersion()\n- vars[\'CMF\'] = get_dist(\'Products.CMFCore\').version\n- vars[\'Debug mode\'] = getConfiguration().debug_mode and \'Yes\' or \'No\'\n+ vars["Zope"] = get_dist("Zope").version\n+ vars["Python"] = sys.version\n+ vars["Platform"] = sys.platform\n+ vars["Plone"] = get_dist("Products.CMFPlone").version\n+ vars["Plone Instance"] = self.getInstanceVersion()\n+ vars["Plone File System"] = self.getFileSystemVersion()\n+ vars["CMF"] = get_dist("Products.CMFCore").version\n+ vars["Debug mode"] = getConfiguration().debug_mode and "Yes" or "No"\n try:\n- vars[\'PIL\'] = get_dist(\'PIL\').version\n+ vars["PIL"] = get_dist("PIL").version\n except pkg_resources.DistributionNotFound:\n try:\n- vars[\'PIL\'] = get_dist(\'PILwoTK\').version\n+ vars["PIL"] = get_dist("PILwoTK").version\n except pkg_resources.DistributionNotFound:\n try:\n- vars[\'PIL\'] = "%s (Pillow)" % get_dist(\'Pillow\').version\n+ vars["PIL"] = "%s (Pillow)" % get_dist("Pillow").version\n except pkg_resources.DistributionNotFound:\n try:\n import _imaging\n+\n _imaging # pyflakes\n- vars[\'PIL\'] = \'unknown\'\n+ vars["PIL"] = "unknown"\n except ImportError:\n pass\n \n return vars\n \n- security.declareProtected(ManagePortal, \'coreVersionsList\')\n+ security.declareProtected(ManagePortal, "coreVersionsList")\n \n def coreVersionsList(self):\n # Useful core information.\n@@ -242,34 +232,34 @@ def coreVersionsList(self):\n res.sort()\n return res\n \n- security.declareProtected(ManagePortal, \'needUpdateRole\')\n+ security.declareProtected(ManagePortal, "needUpdateRole")\n \n def needUpdateRole(self):\n # Do roles need to be updated?\n return self._needUpdateRole\n \n- security.declareProtected(ManagePortal, \'needRecatalog\')\n+ security.declareProtected(ManagePortal, "needRecatalog")\n \n def needRecatalog(self):\n # Does this thing now need recataloging?\n return self._needRecatalog\n \n- security.declareProtected(ManagePortal, \'listUpgrades\')\n+ security.declareProtected(ManagePortal, "listUpgrades")\n \n def listUpgrades(self):\n # List available upgrade steps for our default profile.\n # Do not include upgrade steps for too new versions:\n # using a newer plone.app.upgrade version should not give problems.\n- setup = getToolByName(self, \'portal_setup\')\n+ setup = getToolByName(self, "portal_setup")\n fs_version = self.getFileSystemVersion()\n upgrades = setup.listUpgrades(_DEFAULT_PROFILE, dest=fs_version)\n return upgrades\n \n- security.declareProtected(ManagePortal, \'upgrade\')\n+ security.declareProtected(ManagePortal, "upgrade")\n \n def upgrade(self, REQUEST=None, dry_run=None, swallow_errors=True):\n # Perform the upgrade.\n- setup = getToolByName(self, \'portal_setup\')\n+ setup = getToolByName(self, "portal_setup")\n \n # This sets the profile version if it wasn\'t set yet\n version = self.getInstanceVersion()\n@@ -286,7 +276,7 @@ def upgrade(self, REQUEST=None, dry_run=None, swallow_errors=True):\n handler = logging.StreamHandler(stream)\n handler.setLevel(logging.DEBUG)\n logger.addHandler(handler)\n- gslogger = logging.getLogger(\'GenericSetup\')\n+ gslogger = logging.getLogger("GenericSetup")\n gslogger.addHandler(handler)\n \n if dry_run:\n@@ -296,10 +286,9 @@ def upgrade(self, REQUEST=None, dry_run=None, swallow_errors=True):\n \n for step in steps:\n try:\n- step[\'step\'].doStep(setup)\n- setup.setLastVersionForProfile(\n- _DEFAULT_PROFILE, step[\'dest\'])\n- logger.info("Ran upgrade step: %s" % step[\'title\'])\n+ step["step"].doStep(setup)\n+ setup.setLastVersionForProfile(_DEFAULT_PROFILE, step["dest"])\n+ logger.info("Ran upgrade step: %s" % step["title"])\n except (ConflictError, KeyboardInterrupt):\n raise\n except:\n@@ -329,7 +318,7 @@ def upgrade(self, REQUEST=None, dry_run=None, swallow_errors=True):\n catalog = self.portal_catalog\n # Reduce threshold for the reindex run\n old_threshold = catalog.threshold\n- pg_threshold = getattr(catalog, \'pgthreshold\', 0)\n+ pg_threshold = getattr(catalog, "pgthreshold", 0)\n catalog.pgthreshold = 300\n catalog.threshold = 2000\n catalog.refreshCatalog(clear=1)\n@@ -339,8 +328,9 @@ def upgrade(self, REQUEST=None, dry_run=None, swallow_errors=True):\n except (ConflictError, KeyboardInterrupt):\n raise\n except:\n- logger.error("Exception was thrown while cataloging:"\n- "\\n", exc_info=True)\n+ logger.error(\n+ "Exception was thrown while cataloging:" "\\n", exc_info=True\n+ )\n if not swallow_errors:\n raise\n \n@@ -352,8 +342,10 @@ def upgrade(self, REQUEST=None, dry_run=None, swallow_errors=True):\n except (ConflictError, KeyboardInterrupt):\n raise\n except:\n- logger.error("Exception was thrown while updating "\n- "role mappings", exc_info=True)\n+ logger.error(\n+ "Exception was thrown while updating " "role mappings",\n+ exc_info=True,\n+ )\n if not swallow_errors:\n raise\n logger.info("Your Plone instance is now up-to-date.")\n@@ -372,8 +364,9 @@ def upgrade(self, REQUEST=None, dry_run=None, swallow_errors=True):\n \n \n def registerUpgradePath(oldversion, newversion, function):\n- """ Basic register func """\n+ """Basic register func"""\n pass\n \n+\n InitializeClass(MigrationTool)\n-registerToolInterface(\'portal_migration\', IMigrationTool)\n+registerToolInterface("portal_migration", IMigrationTool)\ndiff --git a/Products/CMFPlone/PasswordResetTool.py b/Products/CMFPlone/PasswordResetTool.py\nindex 620a34a0b7..3b26743aa3 100644\n--- a/Products/CMFPlone/PasswordResetTool.py\n+++ b/Products/CMFPlone/PasswordResetTool.py\n@@ -22,13 +22,14 @@\n import datetime\n \n \n-module_security = ModuleSecurityInfo(\'Products.CMFPlone.PasswordResetTool\')\n+module_security = ModuleSecurityInfo("Products.CMFPlone.PasswordResetTool")\n \n \n @module_security.public\n class InvalidRequestError(Exception):\n- """ Request reset URL is invalid """\n- def __init__(self, value=\'\'):\n+ """Request reset URL is invalid"""\n+\n+ def __init__(self, value=""):\n self.value = value\n \n def __str__(self):\n@@ -37,11 +38,11 @@ def __str__(self):\n \n @module_security.public\n class ExpiredRequestError(InvalidRequestError):\n- """ Request reset URL is expired """\n+ """Request reset URL is expired"""\n \n \n @implementer(IPWResetTool)\n-class PasswordResetTool (UniqueObject, SimpleItem):\n+class PasswordResetTool(UniqueObject, SimpleItem):\n """Provides a default implementation for a password reset scheme.\n \n From a \'forgotten password\' template, you submit your username to\n@@ -52,8 +53,8 @@ class PasswordResetTool (UniqueObject, SimpleItem):\n The user visits that URL (the \'reset form\') and enters their username,\n """\n \n- id = \'portal_password_reset\'\n- meta_type = \'Password Reset Tool\'\n+ id = "portal_password_reset"\n+ meta_type = "Password Reset Tool"\n \n security = ClassSecurityInfo()\n \n@@ -62,7 +63,7 @@ def __init__(self):\n \n # Internal attributes\n _user_check = True\n- _timedelta = 7 # DAYS\n+ _timedelta = 7 # DAYS\n \n # Interface fulfillment ##\n @security.protected(ManagePortal)\n@@ -88,9 +89,9 @@ def requestReset(self, userid):\n self._p_changed = 1\n \n retval = {}\n- retval[\'randomstring\'] = randomstring\n- retval[\'expires\'] = expiry\n- retval[\'userid\'] = userid\n+ retval["randomstring"] = randomstring\n+ retval["expires"] = expiry\n+ retval["userid"] = userid\n return retval\n \n @security.public\n@@ -109,7 +110,8 @@ def resetPassword(self, userid, randomstring, password):\n """\n if get_member_by_login_name:\n found_member = get_member_by_login_name(\n- self, userid, raise_exceptions=False)\n+ self, userid, raise_exceptions=False\n+ )\n if found_member is not None:\n userid = found_member.getId()\n try:\n@@ -130,7 +132,7 @@ def resetPassword(self, userid, randomstring, password):\n \n # actually change password\n user = member.getUser()\n- uf = getToolByName(self, \'acl_users\')\n+ uf = getToolByName(self, "acl_users")\n uf.userSetPassword(user.getUserId(), password)\n member.setMemberProperties(dict(must_change_password=0))\n \n@@ -140,14 +142,12 @@ def resetPassword(self, userid, randomstring, password):\n \n @security.protected(ManagePortal)\n def setExpirationTimeout(self, timedelta):\n- """Set the length of time a reset request will be valid in days.\n- """\n+ """Set the length of time a reset request will be valid in days."""\n self._timedelta = abs(timedelta)\n \n @security.public\n def getExpirationTimeout(self):\n- """Get the length of time a reset request will be valid.\n- """\n+ """Get the length of time a reset request will be valid."""\n return self._timedelta\n \n @security.public\n@@ -158,8 +158,7 @@ def checkUser(self):\n \n @security.public\n def verifyKey(self, key):\n- """Verify a key. Raises an exception if the key is invalid or expired.\n- """\n+ """Verify a key. Raises an exception if the key is invalid or expired."""\n try:\n u, expiry = self._requests[key]\n except KeyError:\n@@ -169,7 +168,7 @@ def verifyKey(self, key):\n raise ExpiredRequestError\n \n if not self.getValidUser(u):\n- raise InvalidRequestError(\'No such user\')\n+ raise InvalidRequestError("No such user")\n \n @security.private\n def clearExpired(self, days=0):\n@@ -207,24 +206,17 @@ def expirationDate(self):\n \n This is used by housekeeping methods (like clearEpired)\n and stored in reset request records."""\n- return (\n- datetime.datetime.utcnow() +\n- datetime.timedelta(days=self._timedelta)\n- )\n+ return datetime.datetime.utcnow() + datetime.timedelta(days=self._timedelta)\n \n @security.private\n def getValidUser(self, userid):\n """Returns the member with \'userid\' if available and None otherwise."""\n if get_member_by_login_name:\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ISecuritySchema, prefix=\'plone\')\n+ settings = registry.forInterface(ISecuritySchema, prefix="plone")\n if settings.use_email_as_login:\n- return get_member_by_login_name(\n- self,\n- userid,\n- raise_exceptions=False\n- )\n- membertool = getToolByName(self, \'portal_membership\')\n+ return get_member_by_login_name(self, userid, raise_exceptions=False)\n+ membertool = getToolByName(self, "portal_membership")\n return membertool.getMemberById(userid)\n \n @security.private\ndiff --git a/Products/CMFPlone/PloneBatch.py b/Products/CMFPlone/PloneBatch.py\nindex b96f72402a..f1a974e1a9 100644\n--- a/Products/CMFPlone/PloneBatch.py\n+++ b/Products/CMFPlone/PloneBatch.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.batch\', \'Version 7.0\')\n+moved("plone.base.batch", "Version 7.0")\ndiff --git a/Products/CMFPlone/PloneControlPanel.py b/Products/CMFPlone/PloneControlPanel.py\nindex d3bdd10096..357ee8ece3 100644\n--- a/Products/CMFPlone/PloneControlPanel.py\n+++ b/Products/CMFPlone/PloneControlPanel.py\n@@ -23,7 +23,6 @@\n \n \n class PloneConfiglet(ActionInformation):\n-\n def __init__(self, appId, **kwargs):\n self.appId = appId\n ActionInformation.__init__(self, **kwargs)\n@@ -39,66 +38,66 @@ def clone(self):\n \n def getAction(self, ec):\n res = ActionInformation.getAction(self, ec)\n- res[\'description\'] = self.getDescription()\n+ res["description"] = self.getDescription()\n return res\n \n \n @implementer(IControlPanel)\n-class PloneControlPanel(PloneBaseTool, UniqueObject,\n- Folder, ActionProviderBase, PropertyManager):\n+class PloneControlPanel(\n+ PloneBaseTool, UniqueObject, Folder, ActionProviderBase, PropertyManager\n+):\n """Weave together the various sources of "actions" which\n are apropos to the current user and context.\n """\n \n security = ClassSecurityInfo()\n \n- id = \'portal_controlpanel\'\n- title = \'Control Panel\'\n- toolicon = \'skins/plone_images/site_icon.png\'\n- meta_type = \'Plone Control Panel Tool\'\n- _actions_form = DTMLFile(\'www/editPloneConfiglets\', globals())\n+ id = "portal_controlpanel"\n+ title = "Control Panel"\n+ toolicon = "skins/plone_images/site_icon.png"\n+ meta_type = "Plone Control Panel Tool"\n+ _actions_form = DTMLFile("www/editPloneConfiglets", globals())\n \n- manage_options = (ActionProviderBase.manage_options +\n- PropertyManager.manage_options)\n+ manage_options = ActionProviderBase.manage_options + PropertyManager.manage_options\n \n group = dict(\n member=[\n- (\'Member\', _(\'My Preferences\')),\n+ ("Member", _("My Preferences")),\n ],\n site=[\n- (\'plone-general\', _(\'General\')),\n- (\'plone-content\', _(\'Content\')),\n- (\'plone-users\', _(\'Users\')),\n- (\'plone-security\', _(\'Security\')),\n- (\'plone-advanced\', _(\'Advanced\')),\n- (\'Plone\', _(\'Plone Configuration\')),\n- (\'Products\', _(\'Add-on Configuration\')),\n- ]\n+ ("plone-general", _("General")),\n+ ("plone-content", _("Content")),\n+ ("plone-users", _("Users")),\n+ ("plone-security", _("Security")),\n+ ("plone-advanced", _("Advanced")),\n+ ("Plone", _("Plone Configuration")),\n+ ("Products", _("Add-on Configuration")),\n+ ],\n )\n \n def __init__(self, **kw):\n if kw:\n self.__dict__.update(**kw)\n \n- security.declareProtected(ManagePortal, \'registerConfiglets\')\n+ security.declareProtected(ManagePortal, "registerConfiglets")\n \n def registerConfiglets(self, configlets):\n for conf in configlets:\n self.registerConfiglet(**conf)\n \n- security.declareProtected(ManagePortal, \'getGroupIds\')\n+ security.declareProtected(ManagePortal, "getGroupIds")\n \n- def getGroupIds(self, category=\'site\'):\n+ def getGroupIds(self, category="site"):\n groups = self.group.get(category, [])\n return [g[0] for g in groups if g]\n \n- security.declareProtected(View, \'getGroups\')\n+ security.declareProtected(View, "getGroups")\n \n- def getGroups(self, category=\'site\'):\n+ def getGroups(self, category="site"):\n groups = self.group.get(category, [])\n- return [{\'id\': g[0], \'title\': g[1]} for g in groups if g]\n+ return [{"id": g[0], "title": g[1]} for g in groups if g]\n \n- security.declarePrivate(\'listActions\')\n+ security.declarePrivate("listActions")\n \n def listActions(self, info=None, object=None):\n # This exists here to shut up a deprecation warning about old-style\n@@ -108,21 +107,21 @@ def listActions(self, info=None, object=None):\n # before CMF 2.4 when support for old-style actions is removed.\n return self._actions or ()\n \n- security.declarePublic(\'maySeeSomeConfiglets\')\n+ security.declarePublic("maySeeSomeConfiglets")\n \n def maySeeSomeConfiglets(self):\n- groups = self.getGroups(\'site\')\n+ groups = self.getGroups("site")\n \n all = []\n for group in groups:\n- all.extend(self.enumConfiglets(group=group[\'id\']))\n- all = [item for item in all if item[\'visible\']]\n+ all.extend(self.enumConfiglets(group=group["id"]))\n+ all = [item for item in all if item["visible"]]\n return len(all) != 0\n \n- security.declarePublic(\'enumConfiglets\')\n+ security.declarePublic("enumConfiglets")\n \n def enumConfiglets(self, group=None):\n- portal = getToolByName(self, \'portal_url\').getPortalObject()\n+ portal = getToolByName(self, "portal_url").getPortalObject()\n context = createExprContext(self, portal, self)\n res = []\n for a in self.listActions():\n@@ -130,24 +129,28 @@ def enumConfiglets(self, group=None):\n for permission in a.permissions:\n if _checkPermission(permission, portal):\n verified = 1\n- if verified and a.category == group and a.visible and a.testCondition(context):\n+ if (\n+ verified\n+ and a.category == group\n+ and a.visible\n+ and a.testCondition(context)\n+ ):\n res.append(a.getAction(context))\n # Translate the title for sorting\n- if getattr(self, \'REQUEST\', None) is not None:\n+ if getattr(self, "REQUEST", None) is not None:\n for a in res:\n- title = a[\'title\']\n+ title = a["title"]\n if not isinstance(title, Message):\n- title = Message(title, domain=\'plone\')\n- a[\'title\'] = translate(title,\n- context=self.REQUEST)\n+ title = Message(title, domain="plone")\n+ a["title"] = translate(title, context=self.REQUEST)\n \n def _title(v):\n- return v[\'title\']\n+ return v["title"]\n \n res.sort(key=_title)\n return res\n \n- security.declareProtected(ManagePortal, \'unregisterConfiglet\')\n+ security.declareProtected(ManagePortal, "unregisterConfiglet")\n \n def unregisterConfiglet(self, id):\n actids = [o.id for o in self.listActions()]\n@@ -156,7 +159,7 @@ def unregisterConfiglet(self, id):\n return\n self.deleteActions(selection)\n \n- security.declareProtected(ManagePortal, \'unregisterApplication\')\n+ security.declareProtected(ManagePortal, "unregisterApplication")\n \n def unregisterApplication(self, appId):\n acts = list(self.listActions())\n@@ -167,28 +170,28 @@ def unregisterApplication(self, appId):\n \n def _extractAction(self, properties, index):\n # Extract an ActionInformation from the funky form properties.\n- id = str(properties.get(\'id_%d\' % index, \'\'))\n- name = str(properties.get(\'name_%d\' % index, \'\'))\n- action = str(properties.get(\'action_%d\' % index, \'\'))\n- condition = str(properties.get(\'condition_%d\' % index, \'\'))\n- category = str(properties.get(\'category_%d\' % index, \'\'))\n- visible = properties.get(\'visible_%d\' % index, 0)\n- permissions = properties.get(\'permission_%d\' % index, ())\n- appId = properties.get(\'appId_%d\' % index, \'\')\n- description = properties.get(\'description_%d\' % index, \'\')\n- icon_expr = properties.get(\'icon_expr_%d\' % index, \'\')\n+ id = str(properties.get("id_%d" % index, ""))\n+ name = str(properties.get("name_%d" % index, ""))\n+ action = str(properties.get("action_%d" % index, ""))\n+ condition = str(properties.get("condition_%d" % index, ""))\n+ category = str(properties.get("category_%d" % index, ""))\n+ visible = properties.get("visible_%d" % index, 0)\n+ permissions = properties.get("permission_%d" % index, ())\n+ appId = properties.get("appId_%d" % index, "")\n+ description = properties.get("description_%d" % index, "")\n+ icon_expr = properties.get("icon_expr_%d" % index, "")\n \n if not name:\n- raise ValueError(\'A name is required.\')\n+ raise ValueError("A name is required.")\n \n- if action != \'\':\n+ if action != "":\n action = Expression(text=action)\n \n- if condition != \'\':\n+ if condition != "":\n condition = Expression(text=condition)\n \n- if category == \'\':\n- category = \'object\'\n+ if category == "":\n+ category = "object"\n \n if not isinstance(visible, int):\n try:\n@@ -197,93 +200,93 @@ def _extractAction(self, properties, index):\n visible = 0\n \n if isinstance(permissions, str):\n- permissions = (permissions, )\n-\n- return PloneConfiglet(id=id,\n- title=name,\n- action=action,\n- condition=condition,\n- permissions=permissions,\n- category=category,\n- visible=visible,\n- appId=appId,\n- description=description,\n- icon_expr=icon_expr,\n- )\n-\n- security.declareProtected(ManagePortal, \'addAction\')\n-\n- def addAction(self,\n- id,\n- name,\n- action,\n- condition=\'\',\n- permission=\'\',\n- category=\'Plone\',\n- visible=1,\n- appId=None,\n- icon_expr=\'\',\n- description=\'\',\n- REQUEST=None,\n- ):\n+ permissions = (permissions,)\n+\n+ return PloneConfiglet(\n+ id=id,\n+ title=name,\n+ action=action,\n+ condition=condition,\n+ permissions=permissions,\n+ category=category,\n+ visible=visible,\n+ appId=appId,\n+ description=description,\n+ icon_expr=icon_expr,\n+ )\n+\n+ security.declareProtected(ManagePortal, "addAction")\n+\n+ def addAction(\n+ self,\n+ id,\n+ name,\n+ action,\n+ condition="",\n+ permission="",\n+ category="Plone",\n+ visible=1,\n+ appId=None,\n+ icon_expr="",\n+ description="",\n+ REQUEST=None,\n+ ):\n """Add an action to our list."""\n if not name:\n- raise ValueError(\'A name is required.\')\n+ raise ValueError("A name is required.")\n \n- a_expr = action and Expression(text=str(action)) or \'\'\n- c_expr = condition and Expression(text=str(condition)) or \'\'\n+ a_expr = action and Expression(text=str(action)) or ""\n+ c_expr = condition and Expression(text=str(condition)) or ""\n \n if not isinstance(permission, tuple):\n- permission = permission and (str(permission), ) or ()\n+ permission = permission and (str(permission),) or ()\n \n new_actions = self._cloneActions()\n \n- new_action = PloneConfiglet(id=str(id),\n- title=name,\n- action=a_expr,\n- condition=c_expr,\n- permissions=permission,\n- category=str(category),\n- visible=int(visible),\n- appId=appId,\n- description=description,\n- icon_expr=icon_expr,\n- )\n+ new_action = PloneConfiglet(\n+ id=str(id),\n+ title=name,\n+ action=a_expr,\n+ condition=c_expr,\n+ permissions=permission,\n+ category=str(category),\n+ visible=int(visible),\n+ appId=appId,\n+ description=description,\n+ icon_expr=icon_expr,\n+ )\n \n new_actions.append(new_action)\n self._actions = tuple(new_actions)\n \n if REQUEST is not None:\n- return self.manage_editActionsForm(\n- REQUEST, manage_tabs_message=\'Added.\')\n+ return self.manage_editActionsForm(REQUEST, manage_tabs_message="Added.")\n \n- security.declareProtected(ManagePortal, \'registerConfiglet\')\n+ security.declareProtected(ManagePortal, "registerConfiglet")\n registerConfiglet = addAction\n \n- security.declareProtected(ManagePortal, \'manage_editActionsForm\')\n+ security.declareProtected(ManagePortal, "manage_editActionsForm")\n \n def manage_editActionsForm(self, REQUEST, manage_tabs_message=None):\n- """ Show the \'Actions\' management tab.\n- """\n+ """Show the \'Actions\' management tab."""\n actions = []\n \n for a in self.listActions():\n-\n a1 = {}\n- a1[\'id\'] = a.getId()\n- a1[\'name\'] = a.Title()\n+ a1["id"] = a.getId()\n+ a1["name"] = a.Title()\n p = a.getPermissions()\n if p:\n- a1[\'permission\'] = p[0]\n+ a1["permission"] = p[0]\n else:\n- a1[\'permission\'] = \'\'\n- a1[\'category\'] = a.getCategory() or \'object\'\n- a1[\'visible\'] = a.getVisibility()\n- a1[\'action\'] = a.getActionExpression()\n- a1[\'condition\'] = a.getCondition()\n- a1[\'appId\'] = a.getAppId()\n- a1[\'description\'] = a.getDescription()\n- a1[\'icon_expr\'] = a.getIconExpression()\n+ a1["permission"] = ""\n+ a1["category"] = a.getCategory() or "object"\n+ a1["visible"] = a.getVisibility()\n+ a1["action"] = a.getActionExpression()\n+ a1["condition"] = a.getCondition()\n+ a1["appId"] = a.getAppId()\n+ a1["description"] = a.getDescription()\n+ a1["icon_expr"] = a.getIconExpression()\n actions.append(a1)\n \n # possible_permissions is in OFS.role.RoleManager.\n@@ -293,7 +296,7 @@ def manage_editActionsForm(self, REQUEST, manage_tabs_message=None):\n REQUEST,\n actions=actions,\n possible_permissions=pp,\n- management_view=\'Actions\',\n+ management_view="Actions",\n manage_tabs_message=manage_tabs_message,\n )\n \n@@ -308,4 +311,4 @@ def site_url(self):\n \n \n InitializeClass(PloneControlPanel)\n-registerToolInterface(\'portal_controlpanel\', IControlPanel)\n+registerToolInterface("portal_controlpanel", IControlPanel)\ndiff --git a/Products/CMFPlone/PloneTool.py b/Products/CMFPlone/PloneTool.py\nindex f3939235be..441ac10c16 100644\n--- a/Products/CMFPlone/PloneTool.py\n+++ b/Products/CMFPlone/PloneTool.py\n@@ -68,7 +68,10 @@\n BAD_CHARS = bad_id.__self__.findall\n \n # max 63 chars per label in domains, see RFC1035\n-EMAIL_RE = re.compile(r"^(\\w&.%#$&\'\\*+-/=?^_`{}|~]+!)*[\\w&.%#$&\'\\*+-/=?^_`{}|~]+@(([0-9a-z]([0-9a-z-]*[0-9a-z])?\\.)+[a-z]{2,63}|([0-9]{1,3}\\.){3}[0-9]{1,3})$", re.IGNORECASE) # noqa\n+EMAIL_RE = re.compile(\n+ r"^(\\w&.%#$&\'\\*+-/=?^_`{}|~]+!)*[\\w&.%#$&\'\\*+-/=?^_`{}|~]+@(([0-9a-z]([0-9a-z-]*[0-9a-z])?\\.)+[a-z]{2,63}|([0-9]{1,3}\\.){3}[0-9]{1,3})$",\n+ re.IGNORECASE,\n+) # noqa\n # used to find double new line (in any variant)\n EMAIL_CUTOFF_RE = re.compile(r".*[\\n\\r][\\n\\r]")\n \n@@ -77,53 +80,55 @@\n # The first two rows are handle in a special way\n # \'Description\' : \'description\',\n # \'Subject\' : \'keywords\',\n- \'Description\': \'DC.description\',\n- \'Subject\': \'DC.subject\',\n- \'Creator\': \'DC.creator\',\n- \'Contributors\': \'DC.contributors\',\n- \'Publisher\': \'DC.publisher\',\n- \'CreationDate\': \'DC.date.created\',\n- \'ModificationDate\': \'DC.date.modified\',\n- \'Type\': \'DC.type\',\n- \'Format\': \'DC.format\',\n- \'Language\': \'DC.language\',\n- \'Rights\': \'DC.rights\',\n+ "Description": "DC.description",\n+ "Subject": "DC.subject",\n+ "Creator": "DC.creator",\n+ "Contributors": "DC.contributors",\n+ "Publisher": "DC.publisher",\n+ "CreationDate": "DC.date.created",\n+ "ModificationDate": "DC.date.modified",\n+ "Type": "DC.type",\n+ "Format": "DC.format",\n+ "Language": "DC.language",\n+ "Rights": "DC.rights",\n }\n-METADATA_DC_AUTHORFIELDS = (\'Creator\', \'Contributors\', \'Publisher\')\n+METADATA_DC_AUTHORFIELDS = ("Creator", "Contributors", "Publisher")\n \n \n @implementer(IPloneTool)\n class PloneTool(PloneBaseTool, UniqueObject, SimpleItem):\n """Various utility methods."""\n \n- id = \'plone_utils\'\n- meta_type = \'Plone Utility Tool\'\n- toolicon = \'skins/plone_images/site_icon.png\'\n+ id = "plone_utils"\n+ meta_type = "Plone Utility Tool"\n+ toolicon = "skins/plone_images/site_icon.png"\n security = ClassSecurityInfo()\n plone_tool = 1\n # Prefix for forms fields!?\n- field_prefix = \'field_\'\n+ field_prefix = "field_"\n \n @security.protected(ManageUsers)\n @protect(CheckAuthenticator)\n def setMemberProperties(self, member, REQUEST=None, **properties):\n- pas = getToolByName(self, \'acl_users\')\n- if safe_hasattr(member, \'getId\'):\n+ pas = getToolByName(self, "acl_users")\n+ if safe_hasattr(member, "getId"):\n member = member.getId()\n user = pas.getUserById(member)\n user.setProperties(**properties)\n \n @security.public\n- @deprecate(\'`getSiteEncoding` is deprecated. Plone only supports UTF-8 \'\n- \'currently. This method always returns "utf-8"\')\n+ @deprecate(\n+ "`getSiteEncoding` is deprecated. Plone only supports UTF-8 "\n+ \'currently. This method always returns "utf-8"\'\n+ )\n def getSiteEncoding(self):\n- """ Get the the site encoding, which is utf-8."""\n- return \'utf-8\'\n+ """Get the the site encoding, which is utf-8."""\n+ return "utf-8"\n \n @security.private\n def getMailHost(self):\n """Gets the MailHost."""\n- return getattr(aq_parent(self), \'MailHost\')\n+ return getattr(aq_parent(self), "MailHost")\n \n @security.public\n def validateSingleNormalizedEmailAddress(self, address):\n@@ -138,8 +143,8 @@ def validateSingleNormalizedEmailAddress(self, address):\n return False\n \n # sub is an empty string if the address is valid\n- sub = EMAIL_RE.sub(\'\', address)\n- if sub == \'\':\n+ sub = EMAIL_RE.sub("", address)\n+ if sub == "":\n return True\n return False\n \n@@ -185,13 +190,24 @@ def validateEmailAddresses(self, addresses):\n return True\n \n @security.public\n- def editMetadata(self, obj, allowDiscussion=None, title=None,\n- subject=None, description=None, contributors=None,\n- effective_date=None, expiration_date=None, format=None,\n- language=None, rights=None, **kwargs):\n+ def editMetadata(\n+ self,\n+ obj,\n+ allowDiscussion=None,\n+ title=None,\n+ subject=None,\n+ description=None,\n+ contributors=None,\n+ effective_date=None,\n+ expiration_date=None,\n+ format=None,\n+ language=None,\n+ rights=None,\n+ **kwargs,\n+ ):\n # Responsible for setting metadata on a content object.\n # We assume the obj implements IDublinCoreMetadata.\n- mt = getToolByName(self, \'portal_membership\')\n+ mt = getToolByName(self, "portal_membership")\n if not mt.checkPermission(ModifyPortalContent, obj):\n # FIXME: Some scripts rely on this being string?\n raise Unauthorized\n@@ -207,25 +223,25 @@ def tuplify(value):\n \n if IDublinCore.providedBy(obj):\n if title is None:\n- title = getfield(REQUEST, \'title\')\n+ title = getfield(REQUEST, "title")\n if description is None:\n- description = getfield(REQUEST, \'description\')\n+ description = getfield(REQUEST, "description")\n if subject is None:\n- subject = getfield(REQUEST, \'subject\')\n+ subject = getfield(REQUEST, "subject")\n if subject is not None:\n subject = tuplify(subject)\n if contributors is None:\n- contributors = getfield(REQUEST, \'contributors\')\n+ contributors = getfield(REQUEST, "contributors")\n if contributors is not None:\n contributors = tuplify(contributors)\n if effective_date is None:\n- effective_date = getfield(REQUEST, \'effective_date\')\n- if effective_date == \'\':\n- effective_date = \'None\'\n+ effective_date = getfield(REQUEST, "effective_date")\n+ if effective_date == "":\n+ effective_date = "None"\n if expiration_date is None:\n- expiration_date = getfield(REQUEST, \'expiration_date\')\n- if expiration_date == \'\':\n- expiration_date = \'None\'\n+ expiration_date = getfield(REQUEST, "expiration_date")\n+ if expiration_date == "":\n+ expiration_date = "None"\n \n if IMutableDublinCore.providedBy(obj):\n if title is not None:\n@@ -252,20 +268,19 @@ def tuplify(value):\n def _renameObject(self, obj, id):\n if not id:\n REQUEST = self.REQUEST\n- id = REQUEST.get(\'id\', \'\')\n- id = REQUEST.get(self.field_prefix + \'id\', \'\')\n+ id = REQUEST.get("id", "")\n+ id = REQUEST.get(self.field_prefix + "id", "")\n if id != obj.getId():\n parent = aq_parent(aq_inner(obj))\n parent.manage_renameObject(obj.getId(), id)\n \n- def _makeTransactionNote(self, obj, msg=\'\'):\n+ def _makeTransactionNote(self, obj, msg=""):\n # TODO Why not aq_parent()?\n- relative_path = \'/\'.join(\n- getToolByName(self, \'portal_url\').getRelativeContentPath(obj)[:-1]\n+ relative_path = "/".join(\n+ getToolByName(self, "portal_url").getRelativeContentPath(obj)[:-1]\n )\n if not msg:\n- msg = relative_path + \'/\' + obj.title_or_id() \\\n- + \' has been modified.\'\n+ msg = relative_path + "/" + obj.title_or_id() + " has been modified."\n if not transaction.get().description:\n transaction_note(safe_text(msg))\n \n@@ -275,24 +290,23 @@ def contentEdit(self, obj, **kwargs):\n try:\n self.editMetadata(obj, **kwargs)\n except AttributeError as msg:\n- log(\'Failure editing metadata at: %s.\\n%s\\n\' %\n- (obj.absolute_url(), msg))\n- if kwargs.get(\'id\', None) is not None:\n- self._renameObject(obj, id=kwargs[\'id\'].strip())\n+ log("Failure editing metadata at: %s.\\n%s\\n" % (obj.absolute_url(), msg))\n+ if kwargs.get("id", None) is not None:\n+ self._renameObject(obj, id=kwargs["id"].strip())\n self._makeTransactionNote(obj)\n \n @security.public\n def availableMIMETypes(self):\n # Returns a map of mimetypes.\n # Requires mimetype registry from Archetypes >= 1.3.\n- mtr = getToolByName(self, \'mimetypes_registry\')\n+ mtr = getToolByName(self, "mimetypes_registry")\n return mtr.list_mimetypes()\n \n @security.protected(View)\n def getWorkflowChainFor(self, object):\n # Proxy the request for the chain to the workflow tool, as\n # this method is private there.\n- wftool = getToolByName(self, \'portal_workflow\')\n+ wftool = getToolByName(self, "portal_workflow")\n wfs = ()\n try:\n wfs = wftool.getChainFor(object)\n@@ -307,16 +321,15 @@ def getIconFor(self, category, id, default=_marker, context=None):\n # Get an icon for an action, from its icon_expr.\n if context is None:\n context = aq_parent(self)\n- action_chain = f\'{category}/{id}\'\n- if category == \'controlpanel\':\n- tool = getToolByName(context, \'portal_controlpanel\')\n- actions = [ai for ai in tool.listActionInfos() if ai[\'id\'] == id]\n+ action_chain = f"{category}/{id}"\n+ if category == "controlpanel":\n+ tool = getToolByName(context, "portal_controlpanel")\n+ actions = [ai for ai in tool.listActionInfos() if ai["id"] == id]\n else:\n- tool = getToolByName(context, \'portal_actions\')\n- actions = tool.listActionInfos(\n- action_chain=action_chain, object=context)\n+ tool = getToolByName(context, "portal_actions")\n+ actions = tool.listActionInfos(action_chain=action_chain, object=context)\n if len(actions) > 0:\n- icon = actions[0].get(\'icon\', None)\n+ icon = actions[0].get("icon", None)\n if icon:\n return icon\n else:\n@@ -332,11 +345,11 @@ def getReviewStateTitleFor(self, obj):\n # Utility method that gets the workflow state title for the\n # object\'s review_state.\n # Returns None if no review_state found.\n- wf_tool = getToolByName(self, \'portal_workflow\')\n+ wf_tool = getToolByName(self, "portal_workflow")\n wfs = ()\n objstate = None\n try:\n- objstate = wf_tool.getInfoFor(obj, \'review_state\')\n+ objstate = wf_tool.getInfoFor(obj, "review_state")\n wfs = wf_tool.getWorkflowsFor(obj)\n except WorkflowException:\n pass\n@@ -350,8 +363,8 @@ def getReviewStateTitleFor(self, obj):\n @protect(CheckAuthenticator)\n def changeOwnershipOf(self, object, userid, recursive=0, REQUEST=None):\n """Changes the ownership of an object."""\n- membership = getToolByName(self, \'portal_membership\')\n- acl_users = getattr(self, \'acl_users\')\n+ membership = getToolByName(self, "portal_membership")\n+ acl_users = getattr(self, "acl_users")\n user = acl_users.getUserById(userid)\n if user is None:\n # The user could be in the top level acl_users folder in\n@@ -359,42 +372,43 @@ def changeOwnershipOf(self, object, userid, recursive=0, REQUEST=None):\n user = membership.getMemberById(userid)\n if user is None:\n raise KeyError(\n- \'Only retrievable users in this site can be made owners.\')\n+ "Only retrievable users in this site can be made owners."\n+ )\n # Be careful not to pass MemberData to changeOwnership\n user = user.getUser()\n object.changeOwnership(user, recursive)\n \n def fixOwnerRole(object, user_id):\n # Get rid of all other owners\n- owners = object.users_with_local_role(\'Owner\')\n+ owners = object.users_with_local_role("Owner")\n for o in owners:\n roles = list(object.get_local_roles_for_userid(o))\n- roles.remove(\'Owner\')\n+ roles.remove("Owner")\n if roles:\n object.manage_setLocalRoles(o, roles)\n else:\n object.manage_delLocalRoles([o])\n # Fix for 1750\n roles = list(object.get_local_roles_for_userid(user_id))\n- roles.append(\'Owner\')\n+ roles.append("Owner")\n object.manage_setLocalRoles(user_id, roles)\n \n fixOwnerRole(object, user.getId())\n- if base_hasattr(object, \'reindexObject\'):\n+ if base_hasattr(object, "reindexObject"):\n object.reindexObject()\n \n if recursive:\n- catalog_tool = getToolByName(self, \'portal_catalog\')\n- purl = getToolByName(self, \'portal_url\')\n+ catalog_tool = getToolByName(self, "portal_catalog")\n+ purl = getToolByName(self, "portal_url")\n _path = purl.getRelativeContentURL(object)\n subobjects = [\n- b.getObject()\n- for b in catalog_tool(path={\'query\': _path, \'level\': 1})\n+ b.getObject() for b in catalog_tool(path={"query": _path, "level": 1})\n ]\n for obj in subobjects:\n fixOwnerRole(obj, user.getId())\n- if base_hasattr(obj, \'reindexObject\'):\n+ if base_hasattr(obj, "reindexObject"):\n obj.reindexObject()\n+\n changeOwnershipOf = postonly(changeOwnershipOf)\n \n @security.public\n@@ -468,13 +482,13 @@ def bad_chars(self, id):\n @security.public\n def getInheritedLocalRoles(self, context):\n # Returns a tuple with the acquired local roles.\n- portal = getToolByName(context, \'portal_url\').getPortalObject()\n+ portal = getToolByName(context, "portal_url").getPortalObject()\n result = []\n cont = 1\n if portal != context:\n parent = aq_parent(context)\n while cont:\n- if not getattr(parent, \'acl_users\', False):\n+ if not getattr(parent, "acl_users", False):\n break\n userroles = parent.acl_users._getLocalRolesForDisplay(parent)\n for user, roles, role_type, name in userroles:\n@@ -535,13 +549,13 @@ def getDefaultPage(self, obj, request=None):\n # Lookup happens over a view, for which in theory a different\n # implementation may be used.\n if request is None:\n- if hasattr(self, \'REQUEST\'):\n+ if hasattr(self, "REQUEST"):\n request = self.REQUEST\n if request:\n return get_default_page_via_view(obj, request)\n \n @security.public\n- def addPortalMessage(self, message, type=\'info\', request=None):\n+ def addPortalMessage(self, message, type="info", request=None):\n # Call this once or more to add messages to be displayed at the\n # top of the web page.\n \n@@ -627,18 +641,18 @@ def browserDefault(self, obj):\n # and then requests that object, for example for: /, with verb PROPFIND\n # means acquire PROPFIND from the folder and call it\n # its all very odd and WebDAV\'y\n- request = getattr(self, \'REQUEST\', None)\n- if request is not None and \'REQUEST_METHOD\' in request:\n- if request[\'REQUEST_METHOD\'] not in [\'GET\', \'POST\']:\n- return obj, [request[\'REQUEST_METHOD\']]\n+ request = getattr(self, "REQUEST", None)\n+ if request is not None and "REQUEST_METHOD" in request:\n+ if request["REQUEST_METHOD"] not in ["GET", "POST"]:\n+ return obj, [request["REQUEST_METHOD"]]\n # Now back to normal\n \n #\n # 1. Get an attribute or contained object index_html\n #\n- index_obj = getattr(aq_base(obj), \'index_html\', None)\n+ index_obj = getattr(aq_base(obj), "index_html", None)\n if index_obj is not None and not isinstance(index_obj, ComputedAttribute):\n- return obj, [\'index_html\']\n+ return obj, ["index_html"]\n \n #\n # 2. Look for a default_page managed by an IBrowserDefault-implementing\n@@ -656,14 +670,13 @@ def browserDefault(self, obj):\n return obj, [defaultPage]\n # Avoid infinite recursion in the case that the page id == the\n # object id\n- elif (\n- defaultPage != obj.getId()\n- and defaultPage != \'/\'.join(obj.getPhysicalPath())\n+ elif defaultPage != obj.getId() and defaultPage != "/".join(\n+ obj.getPhysicalPath()\n ):\n # For the default_page property, we may get things in the\n # skin layers or with an explicit path - split this path\n # to comply with the __browser_default__() spec\n- return obj, defaultPage.split(\'/\')\n+ return obj, defaultPage.split("/")\n \n # 5. If there is no default page, try IBrowserDefault.getLayout()\n if IBrowserDefault.providedBy(obj):\n@@ -672,12 +685,13 @@ def browserDefault(self, obj):\n browserDefault = queryAdapter(obj, IBrowserDefault)\n if browserDefault is not None:\n default_view_fallback = False\n- if base_hasattr(obj, \'getTypeInfo\'):\n+ if base_hasattr(obj, "getTypeInfo"):\n default_view_fallback = obj.getTypeInfo().default_view_fallback\n layout = browserDefault.getLayout(check_exists=default_view_fallback)\n if layout is None:\n raise AttributeError(\n- "%s has no assigned layout, perhaps it needs an FTI" % obj)\n+ "%s has no assigned layout, perhaps it needs an FTI" % obj\n+ )\n else:\n return obj, [layout]\n \n@@ -691,14 +705,16 @@ def browserDefault(self, obj):\n # action (this applies to old-style folders only, IBrowserDefault is\n # managed explicitly above)\n \n- if base_hasattr(obj, \'getTypeInfo\'):\n+ if base_hasattr(obj, "getTypeInfo"):\n try:\n # XXX: This isn\'t quite right since it assumes the action\n # starts with ${object_url}. Should we raise an error if\n # it doesn\'t?\n- act = obj.getTypeInfo().getActionInfo(\n- \'folder/folderlisting\'\n- )[\'url\'].split(\'/\')[-1]\n+ act = (\n+ obj.getTypeInfo()\n+ .getActionInfo("folder/folderlisting")["url"]\n+ .split("/")[-1]\n+ )\n return obj, [act]\n except ValueError:\n pass\n@@ -711,9 +727,9 @@ def browserDefault(self, obj):\n # XXX: This isn\'t quite right since it assumes the action\n # starts with ${object_url}. Should we raise an error if\n # it doesn\'t?\n- act = obj.getTypeInfo().getActionInfo(\n- \'object/view\'\n- )[\'url\'].split(\'/\')[-1]\n+ act = (\n+ obj.getTypeInfo().getActionInfo("object/view")["url"].split("/")[-1]\n+ )\n return obj, [act]\n except ValueError:\n pass\n@@ -723,8 +739,7 @@ def browserDefault(self, obj):\n #\n \n raise AttributeError(\n- "Failed to get a default page or view_action for %s"\n- % (obj.absolute_url(),)\n+ "Failed to get a default page or view_action for %s" % (obj.absolute_url(),)\n )\n \n @security.public\n@@ -735,10 +750,7 @@ def isStructuralFolder(self, obj):\n INonStructuralFolder to declare that it doesn\'t wish to be treated\n as a folder by the navtree, the tab generation etc.\n """\n- return (\n- obj.isPrincipiaFolderish\n- and not INonStructuralFolder.providedBy(obj)\n- )\n+ return obj.isPrincipiaFolderish and not INonStructuralFolder.providedBy(obj)\n \n @security.public\n @protect(CheckAuthenticator)\n@@ -747,7 +759,7 @@ def acquireLocalRoles(self, obj, status=1, REQUEST=None):\n # behaviour).\n # If it\'s 0, prohibit it (it will allow some kind of local role\n # blacklisting).\n- mt = getToolByName(self, \'portal_membership\')\n+ mt = getToolByName(self, "portal_membership")\n if not mt.checkPermission(ModifyPortalContent, obj):\n raise Unauthorized\n \n@@ -756,18 +768,19 @@ def acquireLocalRoles(self, obj, status=1, REQUEST=None):\n if not status:\n obj.__ac_local_roles_block__ = 1\n else:\n- if getattr(obj, \'__ac_local_roles_block__\', None):\n+ if getattr(obj, "__ac_local_roles_block__", None):\n obj.__ac_local_roles_block__ = None\n \n # Reindex the whole stuff.\n obj.reindexObjectSecurity()\n+\n acquireLocalRoles = postonly(acquireLocalRoles)\n \n @security.public\n def isLocalRoleAcquired(self, obj):\n # Returns local role acquisition blocking status.\n # True if normal, false if blocked.\n- if getattr(obj, \'__ac_local_roles_block__\', None):\n+ if getattr(obj, "__ac_local_roles_block__", None):\n return False\n return True\n \n@@ -775,7 +788,7 @@ def isLocalRoleAcquired(self, obj):\n def getOwnerName(self, obj):\n # Returns the userid of the owner of an object.\n # Note: no docstring please, to avoid reflected XSS.\n- mt = getToolByName(self, \'portal_membership\')\n+ mt = getToolByName(self, "portal_membership")\n if not mt.checkPermission(View, obj):\n raise Unauthorized\n return obj.getOwner().getId()\n@@ -797,24 +810,23 @@ def listMetaTags(self, context):\n # Lists meta tags helper.\n # Creates a mapping of meta tags -> values for the listMetaTags script.\n result = {}\n- mt = getToolByName(self, \'portal_membership\')\n+ mt = getToolByName(self, "portal_membership")\n \n registry = getUtility(IRegistry)\n- site_settings = registry.forInterface(\n- ISiteSchema, prefix="plone", check=False)\n+ site_settings = registry.forInterface(ISiteSchema, prefix="plone", check=False)\n \n try:\n use_all = site_settings.exposeDCMetaTags\n except AttributeError:\n use_all = False\n \n- security_settings = registry.forInterface(\n- ISecuritySchema, prefix=\'plone\')\n- view_about = security_settings.allow_anon_views_about \\\n- or not mt.isAnonymousUser()\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n+ view_about = (\n+ security_settings.allow_anon_views_about or not mt.isAnonymousUser()\n+ )\n \n if not use_all:\n- metadata_names = {\'Description\': METADATA_DCNAME[\'Description\']}\n+ metadata_names = {"Description": METADATA_DCNAME["Description"]}\n else:\n metadata_names = METADATA_DCNAME\n for accessor, key in metadata_names.items():\n@@ -823,7 +835,7 @@ def listMetaTags(self, context):\n continue\n \n # short circuit non-special cases\n- if not use_all and accessor not in (\'Description\', \'Subject\'):\n+ if not use_all and accessor not in ("Description", "Subject"):\n continue\n \n method = getattr(aq_inner(context).aq_explicit, accessor, None)\n@@ -839,7 +851,7 @@ def listMetaTags(self, context):\n if not value:\n # No data\n continue\n- if accessor == \'Publisher\' and value == \'No publisher\':\n+ if accessor == "Publisher" and value == "No publisher":\n # No publisher is hardcoded (TODO: still?)\n continue\n \n@@ -852,19 +864,19 @@ def listMetaTags(self, context):\n member = mt.getMemberInfo(userid)\n name = userid\n if member:\n- name = member[\'fullname\'] or userid\n+ name = member["fullname"] or userid\n tmp.append(name)\n value = tmp\n \n if isinstance(value, (list, tuple)):\n # convert a list to a string\n- value = \', \'.join(value)\n+ value = ", ".join(value)\n \n # Special cases\n- if accessor == \'Description\':\n- result[\'description\'] = value\n- elif accessor == \'Subject\':\n- result[\'keywords\'] = value\n+ if accessor == "Description":\n+ result["description"] = value\n+ elif accessor == "Subject":\n+ result["keywords"] = value\n \n if use_all:\n result[key] = value\n@@ -874,7 +886,7 @@ def listMetaTags(self, context):\n \n try:\n effective = context.EffectiveDate()\n- if effective == \'None\':\n+ if effective == "None":\n effective = None\n if effective:\n effective = DateTime(effective)\n@@ -883,7 +895,7 @@ def listMetaTags(self, context):\n \n try:\n expires = context.ExpirationDate()\n- if expires == \'None\':\n+ if expires == "None":\n expires = None\n if expires:\n expires = DateTime(expires)\n@@ -891,20 +903,22 @@ def listMetaTags(self, context):\n expires = None\n \n # Filter out DWIMish artifacts on effective / expiration dates\n- if effective is not None and \\\n- effective > FLOOR_DATE and \\\n- effective != created:\n+ if (\n+ effective is not None\n+ and effective > FLOOR_DATE\n+ and effective != created\n+ ):\n eff_str = effective.Date()\n else:\n- eff_str = \'\'\n+ eff_str = ""\n \n if expires is not None and expires < CEILING_DATE:\n exp_str = expires.Date()\n else:\n- exp_str = \'\'\n+ exp_str = ""\n \n if eff_str or exp_str:\n- result[\'DC.date.valid_range\'] = f\'{eff_str} - {exp_str}\'\n+ result["DC.date.valid_range"] = f"{eff_str} - {exp_str}"\n \n return result\n \n@@ -925,7 +939,7 @@ def getUserFriendlyTypes(self, typesList=None):\n search_settings = registry.forInterface(ISearchSchema, prefix="plone")\n blacklistedTypes = search_settings.types_not_searched\n \n- ttool = getToolByName(self, \'portal_types\')\n+ ttool = getToolByName(self, "portal_types")\n tool_types = ttool.keys()\n if typesList:\n types = [t for t in typesList if t in tool_types]\n@@ -959,7 +973,7 @@ def getMethodAliases(self, typeInfo):\n # Given an FTI, return the dict of method aliases defined on that\n # FTI. If there are no method aliases (i.e. this FTI doesn\'t support\n # it), return None.\n- getMethodAliases = getattr(typeInfo, \'getMethodAliases\', None)\n+ getMethodAliases = getattr(typeInfo, "getMethodAliases", None)\n if getMethodAliases is not None and safe_callable(getMethodAliases):\n return getMethodAliases()\n return None\n@@ -976,12 +990,12 @@ def deleteObjectsByPaths(self, paths, handle_errors=True, REQUEST=None):\n warnings.warn(\n "Use plone.api.content.delete instead of deleteObjectsByPaths. "\n "This method no longer does link integrity checks. Will be removed in Plone 7",\n- DeprecationWarning\n+ DeprecationWarning,\n )\n failure = {}\n success = []\n # use the portal for traversal in case we have relative paths\n- portal = getToolByName(self, \'portal_url\').getPortalObject()\n+ portal = getToolByName(self, "portal_url").getPortalObject()\n traverse = portal.restrictedTraverse\n for path in paths:\n # Skip and note any errors\n@@ -991,7 +1005,7 @@ def deleteObjectsByPaths(self, paths, handle_errors=True, REQUEST=None):\n obj = traverse(path)\n obj_parent = aq_parent(aq_inner(obj))\n obj_parent.manage_delObjects([obj.getId()])\n- success.append(f\'{obj.getId()} ({path})\')\n+ success.append(f"{obj.getId()} ({path})")\n except ConflictError:\n raise\n except Exception as e:\n@@ -1001,17 +1015,18 @@ def deleteObjectsByPaths(self, paths, handle_errors=True, REQUEST=None):\n log_exc()\n else:\n raise\n- transaction_note(\'Deleted %s\' % (\', \'.join(success)))\n+ transaction_note("Deleted %s" % (", ".join(success)))\n return success, failure\n \n @security.public\n @protect(CheckAuthenticator)\n- def renameObjectsByPaths(self, paths, new_ids, new_titles,\n- handle_errors=True, REQUEST=None):\n+ def renameObjectsByPaths(\n+ self, paths, new_ids, new_titles, handle_errors=True, REQUEST=None\n+ ):\n failure = {}\n success = {}\n # use the portal for traversal in case we have relative paths\n- portal = getToolByName(self, \'portal_url\').getPortalObject()\n+ portal = getToolByName(self, "portal_url").getPortalObject()\n traverse = portal.restrictedTraverse\n for i, path in enumerate(paths):\n new_id = new_ids[i]\n@@ -1025,9 +1040,7 @@ def renameObjectsByPaths(self, paths, new_ids, new_titles,\n change_title = new_title and title != new_title\n changed = False\n if change_title:\n- getSecurityManager().validate(\n- obj, obj, \'setTitle\', obj.setTitle\n- )\n+ getSecurityManager().validate(obj, obj, "setTitle", obj.setTitle)\n obj.setTitle(new_title)\n notify(ObjectModifiedEvent(obj))\n changed = True\n@@ -1049,8 +1062,10 @@ def renameObjectsByPaths(self, paths, new_ids, new_titles,\n failure[path] = e\n else:\n raise\n- transaction_note(\'Renamed %s\' % str(success.keys()))\n+ transaction_note("Renamed %s" % str(success.keys()))\n return success, failure\n+\n renameObjectsByPaths = postonly(renameObjectsByPaths)\n \n+\n InitializeClass(PloneTool)\ndiff --git a/Products/CMFPlone/Portal.py b/Products/CMFPlone/Portal.py\nindex 15541f38b8..150e57930e 100644\n--- a/Products/CMFPlone/Portal.py\n+++ b/Products/CMFPlone/Portal.py\n@@ -47,10 +47,10 @@\n \n @implementer(IPloneSiteRoot, ISiteRoot, ISyndicatable, IObjectManagerSite)\n class PloneSite(Container, SkinnableObjectManager, UniqueObject):\n- """ The Plone site object. """\n+ """The Plone site object."""\n \n security = ClassSecurityInfo()\n- meta_type = portal_type = \'Plone Site\'\n+ meta_type = portal_type = "Plone Site"\n \n # Ensure certain attributes come from the correct base class.\n _checkId = SkinnableObjectManager._checkId\n@@ -80,9 +80,7 @@ def __delattr__(self, name):\n \n # Removes the \'Components Folder\'\n \n- manage_options = (\n- Container.manage_options[:2] +\n- Container.manage_options[3:])\n+ manage_options = Container.manage_options[:2] + Container.manage_options[3:]\n \n __ac_permissions__ = (\n (AccessContentsInformation, ()),\n@@ -96,35 +94,42 @@ def __delattr__(self, name):\n (AddPortalFolders, ()),\n (ListPortalMembers, ()),\n (ReplyToItem, ()),\n- (View, (\'isEffective\',)),\n- (ModifyPortalContent, (\'manage_cutObjects\', \'manage_pasteObjects\',\n- \'manage_renameForm\', \'manage_renameObject\',\n- \'manage_renameObjects\')))\n+ (View, ("isEffective",)),\n+ (\n+ ModifyPortalContent,\n+ (\n+ "manage_cutObjects",\n+ "manage_pasteObjects",\n+ "manage_renameForm",\n+ "manage_renameObject",\n+ "manage_renameObjects",\n+ ),\n+ ),\n+ )\n \n # Switch off ZMI ordering interface as it assumes a slightly\n # different functionality\n has_order_support = 0\n- management_page_charset = \'utf-8\'\n- _default_sort_key = \'id\'\n+ management_page_charset = "utf-8"\n+ _default_sort_key = "id"\n _properties = (\n- {\'id\': \'title\', \'type\': \'string\', \'mode\': \'w\'},\n- {\'id\': \'description\', \'type\': \'text\', \'mode\': \'w\'},\n+ {"id": "title", "type": "string", "mode": "w"},\n+ {"id": "description", "type": "text", "mode": "w"},\n )\n- title = \'\'\n- description = \'\'\n- icon = \'misc_/CMFPlone/tool.gif\'\n+ title = ""\n+ description = ""\n+ icon = "misc_/CMFPlone/tool.gif"\n \n # From PortalObjectBase\n- def __init__(self, id, title=\'\'):\n+ def __init__(self, id, title=""):\n super().__init__(id, title=title)\n- components = PersistentComponents(\'++etc++site\')\n+ components = PersistentComponents("++etc++site")\n components.__parent__ = self\n self.setSiteManager(components)\n \n # From PortalObjectBase\n def __before_publishing_traverse__(self, arg1, arg2=None):\n- """ Pre-traversal hook.\n- """\n+ """Pre-traversal hook."""\n # XXX hack around a bug(?) in BeforeTraverse.MultiHook\n REQUEST = arg2 or arg1\n \n@@ -143,35 +148,39 @@ def tpValues(self):\n # Return a list of subobjects, used by ZMI tree tag (and only there).\n # see also https://github.com/plone/Products.CMFPlone/issues/3323\n return sorted(\n- (obj for obj in self.objectValues() if getattr(aq_base(obj), \'isPrincipiaFolderish\', False)),\n+ (\n+ obj\n+ for obj in self.objectValues()\n+ if getattr(aq_base(obj), "isPrincipiaFolderish", False)\n+ ),\n key=lambda obj: obj.getId(),\n )\n \n def __browser_default__(self, request):\n- """ Set default so we can return whatever we want instead\n- of index_html """\n- return getToolByName(self, \'plone_utils\').browserDefault(self)\n+ """Set default so we can return whatever we want instead\n+ of index_html"""\n+ return getToolByName(self, "plone_utils").browserDefault(self)\n \n def index_html(self):\n- """ Acquire if not present. """\n- request = getattr(self, \'REQUEST\', None)\n+ """Acquire if not present."""\n+ request = getattr(self, "REQUEST", None)\n if (\n request is not None\n- and \'REQUEST_METHOD\' in request\n+ and "REQUEST_METHOD" in request\n and request.maybe_webdav_client\n ):\n- method = request[\'REQUEST_METHOD\']\n- if bbb.HAS_ZSERVER and method in (\'PUT\', ):\n+ method = request["REQUEST_METHOD"]\n+ if bbb.HAS_ZSERVER and method in ("PUT",):\n # Very likely a WebDAV client trying to create something\n- result = NullResource(self, \'index_html\')\n- setattr(result, \'__replaceable__\', REPLACEABLE)\n+ result = NullResource(self, "index_html")\n+ setattr(result, "__replaceable__", REPLACEABLE)\n return result\n- elif method not in (\'GET\', \'HEAD\', \'POST\'):\n- raise AttributeError(\'index_html\')\n+ elif method not in ("GET", "HEAD", "POST"):\n+ raise AttributeError("index_html")\n # Acquire from skin.\n- _target = self.__getattr__(\'index_html\')\n+ _target = self.__getattr__("index_html")\n result = aq_base(_target).__of__(self)\n- setattr(result, \'__replaceable__\', REPLACEABLE)\n+ setattr(result, "__replaceable__", REPLACEABLE)\n return result\n \n index_html = ComputedAttribute(index_html, 1)\n@@ -179,8 +188,7 @@ def index_html(self):\n def manage_beforeDelete(self, container, item):\n # Should send out an Event before Site is being deleted.\n self.removal_inprogress = 1\n- PloneSite.inheritedAttribute(\'manage_beforeDelete\')(self, container,\n- item)\n+ PloneSite.inheritedAttribute("manage_beforeDelete")(self, container, item)\n \n @security.protected(permissions.DeleteObjects)\n def manage_delObjects(self, ids=None, REQUEST=None):\n@@ -192,12 +200,11 @@ def manage_delObjects(self, ids=None, REQUEST=None):\n for id in ids:\n item = self._getOb(id)\n if not _checkPermission(permissions.DeleteObjects, item):\n- raise Unauthorized(\n- "Do not have permissions to remove this object")\n+ raise Unauthorized("Do not have permissions to remove this object")\n return PortalObjectBase.manage_delObjects(self, ids, REQUEST=REQUEST)\n \n def view(self):\n- """ Ensure that we get a plain view of the object, via a delegation to\n+ """Ensure that we get a plain view of the object, via a delegation to\n __call__(), which is defined in BrowserDefaultMixin\n """\n return self()\ndiff --git a/Products/CMFPlone/PropertiesTool.py b/Products/CMFPlone/PropertiesTool.py\nindex f0ea227709..4cc6feb44e 100644\n--- a/Products/CMFPlone/PropertiesTool.py\n+++ b/Products/CMFPlone/PropertiesTool.py\n@@ -23,59 +23,56 @@\n \n @implementer(IPropertiesTool)\n class PropertiesTool(PloneBaseTool, Folder, UniqueObject):\n- """ Plone properties tool\n- """\n+ """Plone properties tool"""\n \n- id = \'portal_properties\'\n- toolicon = \'skins/plone_images/topic_icon.png\'\n+ id = "portal_properties"\n+ toolicon = "skins/plone_images/topic_icon.png"\n \n- meta_type = \'Plone Properties Tool\'\n- meta_types = ((\n- {\'name\': \'Plone Property Sheet\',\n- \'action\': \'manage_addPropertySheetForm\'},\n- ))\n+ meta_type = "Plone Properties Tool"\n+ meta_types = (\n+ {"name": "Plone Property Sheet", "action": "manage_addPropertySheetForm"},\n+ )\n \n- manage_options = ((Folder.manage_options[0], ) +\n- ({\'label\': \'Overview\',\n- \'action\': \'manage_overview\'},) +\n- SimpleItem.manage_options)\n+ manage_options = (\n+ (Folder.manage_options[0],)\n+ + ({"label": "Overview", "action": "manage_overview"},)\n+ + SimpleItem.manage_options\n+ )\n \n- manage_addPropertySheetForm = PageTemplateFile(\'www/addPropertySheet\',\n- globals())\n+ manage_addPropertySheetForm = PageTemplateFile("www/addPropertySheet", globals())\n \n security = ClassSecurityInfo()\n \n- security.declareProtected(ManagePortal, \'manage_overview\')\n- manage_overview = DTMLFile(\'explainPropertiesTool\', WWW_DIR)\n+ security.declareProtected(ManagePortal, "manage_overview")\n+ manage_overview = DTMLFile("explainPropertiesTool", WWW_DIR)\n \n def all_meta_types(self, interfaces=None):\n return self.meta_types\n \n- security.declareProtected(ManagePortal, \'addPropertySheet\')\n+ security.declareProtected(ManagePortal, "addPropertySheet")\n \n- def addPropertySheet(self, id, title=\'\', propertysheet=None):\n+ def addPropertySheet(self, id, title="", propertysheet=None):\n # Add a new PropertySheet.\n o = SimpleItemWithProperties(id, title)\n \n # copy the propertysheet values onto the new instance\n if propertysheet is not None:\n- if not hasattr(propertysheet, \'propertyIds\'):\n- raise TypeError(\'propertysheet needs to be a PropertyManager\')\n+ if not hasattr(propertysheet, "propertyIds"):\n+ raise TypeError("propertysheet needs to be a PropertyManager")\n \n for property in propertysheet.propertyMap():\n- pid = property.get(\'id\')\n- ptype = property.get(\'type\')\n+ pid = property.get("id")\n+ ptype = property.get("type")\n pvalue = propertysheet.getProperty(pid)\n if not hasattr(o, pid):\n o._setProperty(pid, pvalue, ptype)\n \n self._setObject(id, o)\n \n- security.declareProtected(ManagePortal, \'manage_addPropertySheet\')\n+ security.declareProtected(ManagePortal, "manage_addPropertySheet")\n \n- def manage_addPropertySheet(self, id, title=\'\',\n- propertysheet=None, REQUEST=None):\n- """ Add a instance of a Property Sheet if handed a\n+ def manage_addPropertySheet(self, id, title="", propertysheet=None, REQUEST=None):\n+ """Add a instance of a Property Sheet if handed a\n propertysheet put the properties into new propertysheet.\n """\n self.addPropertySheet(id, title, propertysheet)\n@@ -86,14 +83,14 @@ def manage_addPropertySheet(self, id, title=\'\',\n #\n # \'portal_properties\' interface methods\n #\n- security.declareProtected(ManagePortal, \'editProperties\')\n+ security.declareProtected(ManagePortal, "editProperties")\n \n def editProperties(self, props):\n # Change portal settings.\n aq_parent(aq_inner(self)).manage_changeProperties(props)\n- if hasattr(self, \'propertysheets\'):\n+ if hasattr(self, "propertysheets"):\n ps = self.propertysheets\n- if hasattr(ps, \'props\'):\n+ if hasattr(ps, "props"):\n ps.props.manage_changeProperties(props)\n \n def title(self):\n@@ -106,7 +103,6 @@ def title(self):\n def smtp_server(self):\n return getUtility(IMailHost).smtp_host\n \n-\n @deprecate(\n "The portal portal_properties tool will be removed in Plone 6.1. "\n "Use the portal_registry instead. "\n@@ -121,20 +117,19 @@ def hasProperty(self, id):\n \n \n @implementer(ISimpleItemWithProperties)\n-class SimpleItemWithProperties (PropertyManager, SimpleItem):\n+class SimpleItemWithProperties(PropertyManager, SimpleItem):\n """\n A common base class for objects with configurable\n properties in a fixed schema.\n """\n \n- def __init__(self, id, title=\'\'):\n+ def __init__(self, id, title=""):\n self.id = id\n self.title = title\n \n- meta_type = \'Plone Property Sheet\'\n+ meta_type = "Plone Property Sheet"\n \n- manage_options = (PropertyManager.manage_options\n- + SimpleItem.manage_options)\n+ manage_options = PropertyManager.manage_options + SimpleItem.manage_options\n \n @deprecate(\n "The portal portal_properties tool will be removed in Plone 6.1. "\ndiff --git a/Products/CMFPlone/RegistrationTool.py b/Products/CMFPlone/RegistrationTool.py\nindex 1e2fc043c8..cc41fd290d 100644\n--- a/Products/CMFPlone/RegistrationTool.py\n+++ b/Products/CMFPlone/RegistrationTool.py\n@@ -45,17 +45,17 @@\n # - remove \'1\', \'l\', and \'I\' to avoid confusion\n # - remove \'0\', \'O\', and \'Q\' to avoid confusion\n # - remove vowels to avoid spelling words\n-invalid_password_chars = [\'a\', \'e\', \'i\', \'o\', \'u\', \'y\', \'l\', \'q\']\n+invalid_password_chars = ["a", "e", "i", "o", "u", "y", "l", "q"]\n \n \n def getValidPasswordChars():\n password_chars = []\n for i in range(0, 26):\n- if chr(ord(\'a\') + i) not in invalid_password_chars:\n- password_chars.append(chr(ord(\'a\') + i))\n- password_chars.append(chr(ord(\'A\') + i))\n+ if chr(ord("a") + i) not in invalid_password_chars:\n+ password_chars.append(chr(ord("a") + i))\n+ password_chars.append(chr(ord("A") + i))\n for i in range(2, 10):\n- password_chars.append(chr(ord(\'0\') + i))\n+ password_chars.append(chr(ord("0") + i))\n return password_chars\n \n \n@@ -70,7 +70,7 @@ def get_member_by_login_name(context, login_name, raise_exceptions=True):\n \n If raise_exceptions is False, we silently return None.\n """\n- membership = getToolByName(context, \'portal_membership\')\n+ membership = getToolByName(context, "portal_membership")\n # First the easy case: it may be a userid after all.\n member = membership.getMemberById(login_name)\n \n@@ -78,45 +78,46 @@ def get_member_by_login_name(context, login_name, raise_exceptions=True):\n return member\n \n # Try to find this user via the login name.\n- acl = getToolByName(context, \'acl_users\')\n- userids = [user.get(\'userid\') for user in\n- acl.searchUsers(name=login_name, exact_match=True)\n- if user.get(\'userid\')]\n+ acl = getToolByName(context, "acl_users")\n+ userids = [\n+ user.get("userid")\n+ for user in acl.searchUsers(name=login_name, exact_match=True)\n+ if user.get("userid")\n+ ]\n if len(userids) == 1:\n userid = userids[0]\n member = membership.getMemberById(userid)\n elif len(userids) > 1:\n if raise_exceptions:\n- raise ValueError(\n- _(\'Multiple users found with the same login name.\'))\n+ raise ValueError(_("Multiple users found with the same login name."))\n if member is None and raise_exceptions:\n- raise ValueError(_(\'The username you entered could not be found.\'))\n+ raise ValueError(_("The username you entered could not be found."))\n return member\n \n+\n # seed the random number generator\n random.seed()\n \n \n class RegistrationTool(PloneBaseTool, BaseTool):\n- """ Manage through-the-web signup policies.\n- """\n+ """Manage through-the-web signup policies."""\n \n- meta_type = \'Plone Registration Tool\'\n+ meta_type = "Plone Registration Tool"\n security = ClassSecurityInfo()\n- toolicon = \'skins/plone_images/pencil_icon.png\'\n+ toolicon = "skins/plone_images/pencil_icon.png"\n plone_tool = 1\n md5key = None\n _v_md5base = None\n- default_member_id_pattern = r\'^\\w[\\w\\.\\-@]+\\w$\'\n+ default_member_id_pattern = r"^\\w[\\w\\.\\-@]+\\w$"\n _ALLOWED_MEMBER_ID_PATTERN = re.compile(default_member_id_pattern)\n \n def __init__(self):\n- if hasattr(BaseTool, \'__init__\'):\n+ if hasattr(BaseTool, "__init__"):\n BaseTool.__init__(self)\n # build and persist an MD5 key\n- self.md5key = \'\'\n+ self.md5key = ""\n for i in range(0, 20):\n- self.md5key += chr(ord(\'a\') + random.randint(0, 26))\n+ self.md5key += chr(ord("a") + random.randint(0, 26))\n \n def _md5base(self):\n if self._v_md5base is None:\n@@ -127,13 +128,15 @@ def _md5base(self):\n return self._v_md5base\n \n def _getValidEmailAddress(self, member):\n- email = member.getProperty(\'email\')\n+ email = member.getProperty("email")\n \n # assert that we can actually get an email address, otherwise\n # the template will be made with a blank To:, this is bad\n if email is None:\n- msg = _(\'No email address is registered for member: \'\n- \'${member_id}\', mapping={\'member_id\': member.getId()})\n+ msg = _(\n+ "No email address is registered for member: " "${member_id}",\n+ mapping={"member_id": member.getId()},\n+ )\n raise ValueError(msg)\n \n checkEmailAddress(email)\n@@ -150,7 +153,7 @@ def getPassword(self, length=5, s=None):\n global password_chars, md5base\n \n if s is None:\n- password = \'\'\n+ password = ""\n nchars = len(password_chars)\n for i in range(0, length):\n password += password_chars[random.randint(0, nchars - 1)]\n@@ -161,14 +164,14 @@ def getPassword(self, length=5, s=None):\n m = self._md5base().copy()\n m.update(s)\n d = m.digest() # compute md5(md5key + s)\n- assert(len(d) >= length)\n- password = \'\'\n+ assert len(d) >= length\n+ password = ""\n nchars = len(password_chars)\n for idx in range(0, length):\n password += password_chars[d[idx] % nchars]\n return password\n \n- security.declarePublic(\'isValidEmail\')\n+ security.declarePublic("isValidEmail")\n \n def isValidEmail(self, email):\n # Checks for valid email.\n@@ -184,20 +187,21 @@ def isValidEmail(self, email):\n #\n # \'portal_registration\' interface\n #\n- security.declarePublic(\'testPasswordValidity\')\n+ security.declarePublic("testPasswordValidity")\n \n def testPasswordValidity(self, password, confirm=None):\n # Verify that the password satisfies the portal\'s requirements.\n #\n # o If the password is valid, return None.\n # o If not, return a string explaining why.\n- err = self.pasValidation(\'password\', password)\n+ err = self.pasValidation("password", password)\n if err:\n return err\n \n if confirm is not None and confirm != password:\n- return _(\'Your password and confirmation did not match. \'\n- \'Please try again.\')\n+ return _(\n+ "Your password and confirmation did not match. " "Please try again."\n+ )\n return None\n \n def pasValidation(self, property, password):\n@@ -211,25 +215,27 @@ def pasValidation(self, property, password):\n err = ""\n for validator_id, validator in validators:\n user = None\n- set_id = \'\'\n+ set_id = ""\n set_info = {property: password}\n errors = validator.validateUserInfo(user, set_id, set_info)\n # We will assume that the PASPlugin returns a list of error\n # strings that have already been translated.\n # We just need to join them in an i18n friendly way\n- for error in [info[\'error\'] for info in errors if info[\'id\'] == property]:\n+ for error in [info["error"] for info in errors if info["id"] == property]:\n if not err:\n err = error\n else:\n- msgid = _(\'${sentances}. ${sentance}\',\n- mapping={\'sentances\': err, \'sentance\': error})\n+ msgid = _(\n+ "${sentances}. ${sentance}",\n+ mapping={"sentances": err, "sentance": error},\n+ )\n err = self.translate(msgid)\n if not err:\n return None\n else:\n return err\n \n- security.declarePublic(\'testPropertiesValidity\')\n+ security.declarePublic("testPropertiesValidity")\n \n def testPropertiesValidity(self, props, member=None):\n # Verify that the properties supplied satisfy portal\'s requirements.\n@@ -240,54 +246,54 @@ def testPropertiesValidity(self, props, member=None):\n # We also check if the email property is writable before verifying it.\n \n if member is None: # New member.\n-\n- username = props.get(\'username\', \'\')\n+ username = props.get("username", "")\n if not username:\n- return _(\'You must enter a valid name.\')\n+ return _("You must enter a valid name.")\n \n if not self.isMemberIdAllowed(username):\n- return _(\'The login name you selected is already in use or \'\n- \'is not valid. Please choose another.\')\n+ return _(\n+ "The login name you selected is already in use or "\n+ "is not valid. Please choose another."\n+ )\n \n- email = props.get(\'email\')\n+ email = props.get("email")\n if email is None:\n- return _(\'You must enter an email address.\')\n+ return _("You must enter an email address.")\n \n try:\n checkEmailAddress(email)\n except EmailAddressInvalid:\n- return _(\'You must enter a valid email address.\')\n+ return _("You must enter a valid email address.")\n \n else: # Existing member.\n- if not hasattr(member, \'canWriteProperty\') or \\\n- member.canWriteProperty(\'email\'):\n-\n- email = props.get(\'email\')\n+ if not hasattr(member, "canWriteProperty") or member.canWriteProperty(\n+ "email"\n+ ):\n+ email = props.get("email")\n \n if email is not None:\n-\n try:\n checkEmailAddress(email)\n except EmailAddressInvalid:\n- return _(\'You must enter a valid email address.\')\n+ return _("You must enter a valid email address.")\n \n # Not allowed to clear an existing non-empty email.\n- existing = member.getProperty(\'email\')\n+ existing = member.getProperty("email")\n \n- if existing and email == \'\':\n- return _(\'You must enter a valid email address.\')\n+ if existing and email == "":\n+ return _("You must enter a valid email address.")\n \n return None\n \n- security.declareProtected(AddPortalMember, \'isMemberIdAllowed\')\n+ security.declareProtected(AddPortalMember, "isMemberIdAllowed")\n \n def isMemberIdAllowed(self, id):\n- if len(id) < 1 or id == \'Anonymous User\':\n+ if len(id) < 1 or id == "Anonymous User":\n return 0\n if not self._ALLOWED_MEMBER_ID_PATTERN.match(id):\n return 0\n \n- pas = getToolByName(self, \'acl_users\')\n+ pas = getToolByName(self, "acl_users")\n if IPluggableAuthService.providedBy(pas):\n results = pas.searchPrincipals(id=id, exact_match=True)\n if results:\n@@ -297,30 +303,28 @@ def isMemberIdAllowed(self, id):\n if hasattr(aq_base(parent), "acl_users"):\n parent = parent.acl_users\n if IPluggableAuthService.providedBy(parent):\n- if parent.searchPrincipals(id=id,\n- exact_match=True):\n+ if parent.searchPrincipals(id=id, exact_match=True):\n return 0\n # When email addresses are used as logins, we need to check\n # if there are any users with the requested login.\n registry = getUtility(IRegistry)\n- security_settings = registry.forInterface(\n- ISecuritySchema, prefix=\'plone\')\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n \n if security_settings.use_email_as_login:\n results = pas.searchUsers(name=id, exact_match=True)\n if results:\n return 0\n else:\n- membership = getToolByName(self, \'portal_membership\')\n+ membership = getToolByName(self, "portal_membership")\n if membership.getMemberById(id) is not None:\n return 0\n- groups = getToolByName(self, \'portal_groups\')\n+ groups = getToolByName(self, "portal_groups")\n if groups.getGroupById(id) is not None:\n return 0\n \n return 1\n \n- security.declarePublic(\'generatePassword\')\n+ security.declarePublic("generatePassword")\n \n def generatePassword(self):\n # Generate a strong default password. The user never gets sent\n@@ -328,52 +332,49 @@ def generatePassword(self):\n \n return self.getPassword(56)\n \n- security.declarePublic(\'generateResetCode\')\n+ security.declarePublic("generateResetCode")\n \n def generateResetCode(self, salt, length=14):\n # Generates a reset code which is guaranteed to return the\n # same value for a given length and salt, every time.\n return self.getPassword(length, salt)\n \n- security.declarePublic(\'mailPassword\')\n+ security.declarePublic("mailPassword")\n \n def mailPassword(self, login, REQUEST, immediate=False):\n- """ Wrapper around mailPassword """\n- membership = getToolByName(self, \'portal_membership\')\n- if not membership.checkPermission(\'Mail forgotten password\', self):\n- raise Unauthorized(\n- _("Mailing forgotten passwords has been disabled."))\n+ """Wrapper around mailPassword"""\n+ membership = getToolByName(self, "portal_membership")\n+ if not membership.checkPermission("Mail forgotten password", self):\n+ raise Unauthorized(_("Mailing forgotten passwords has been disabled."))\n \n- utils = getToolByName(self, \'plone_utils\')\n+ utils = getToolByName(self, "plone_utils")\n member = get_member_by_login_name(self, login, raise_exceptions=False)\n \n if member is None:\n- raise ValueError(\n- _(\'The username you entered could not be found.\'))\n+ raise ValueError(_("The username you entered could not be found."))\n \n # Make sure the user is allowed to set the password.\n- portal = getToolByName(self, \'portal_url\').getPortalObject()\n- acl_users = getToolByName(portal, \'acl_users\')\n+ portal = getToolByName(self, "portal_url").getPortalObject()\n+ acl_users = getToolByName(portal, "acl_users")\n user = acl_users.getUserById(member.getId())\n orig_sm = getSecurityManager()\n try:\n newSecurityManager(REQUEST or self.REQUEST, user)\n tmp_sm = getSecurityManager()\n if not tmp_sm.checkPermission(SetOwnPassword, portal):\n- raise Unauthorized(\n- _("Mailing forgotten passwords has been disabled."))\n+ raise Unauthorized(_("Mailing forgotten passwords has been disabled."))\n finally:\n setSecurityManager(orig_sm)\n \n # assert that we can actually get an email address, otherwise\n # the template will be made with a blank To:, this is bad\n- email = member.getProperty(\'email\')\n+ email = member.getProperty("email")\n if not email:\n- raise ValueError(_(\'That user does not have an email address.\'))\n+ raise ValueError(_("That user does not have an email address."))\n else:\n # add the single email address\n if not utils.validateSingleEmailAddress(email):\n- raise ValueError(_(\'The email address did not validate.\'))\n+ raise ValueError(_("The email address did not validate."))\n check, msg = _checkEmail(email)\n if not check:\n raise ValueError(msg)\n@@ -381,98 +382,123 @@ def mailPassword(self, login, REQUEST, immediate=False):\n # Rather than have the template try to use the mailhost, we will\n # render the message ourselves and send it from here (where we\n # don\'t need to worry about \'UseMailHost\' permissions).\n- reset_tool = getToolByName(self, \'portal_password_reset\')\n+ reset_tool = getToolByName(self, "portal_password_reset")\n reset = reset_tool.requestReset(member.getId())\n \n registry = getUtility(IRegistry)\n- encoding = registry.get(\'plone.email_charset\', \'utf-8\')\n+ encoding = registry.get("plone.email_charset", "utf-8")\n mail_password_template = getMultiAdapter(\n- (self, self.REQUEST), name=\'mail_password_template\')\n+ (self, self.REQUEST), name="mail_password_template"\n+ )\n mail_text = mail_password_template(\n- member=member, reset=reset,\n- password=member.getPassword(), charset=encoding)\n+ member=member, reset=reset, password=member.getPassword(), charset=encoding\n+ )\n # The mail headers are not properly encoded we need to extract\n # them and let MailHost manage the encoding.\n message_obj = message_from_string(mail_text.strip())\n- subject = message_obj[\'Subject\']\n- m_to = message_obj[\'To\']\n- m_from = message_obj[\'From\']\n- msg_type = message_obj.get(\'Content-Type\', \'text/plain\')\n- host = getToolByName(self, \'MailHost\')\n+ subject = message_obj["Subject"]\n+ m_to = message_obj["To"]\n+ m_from = message_obj["From"]\n+ msg_type = message_obj.get("Content-Type", "text/plain")\n+ host = getToolByName(self, "MailHost")\n try:\n- host.send(mail_text, m_to, m_from, subject=subject,\n- charset=encoding, immediate=immediate,\n- msg_type=msg_type)\n+ host.send(\n+ mail_text,\n+ m_to,\n+ m_from,\n+ subject=subject,\n+ charset=encoding,\n+ immediate=immediate,\n+ msg_type=msg_type,\n+ )\n except SMTPRecipientsRefused:\n # Don\'t disclose email address on failure\n- raise SMTPRecipientsRefused(\n- _(\'Recipient address rejected by server.\'))\n+ raise SMTPRecipientsRefused(_("Recipient address rejected by server."))\n except SMTPException as e:\n- raise(e)\n+ raise (e)\n mail_password_response = getMultiAdapter(\n- (self, self.REQUEST), name=\'mail_password_response\')\n+ (self, self.REQUEST), name="mail_password_response"\n+ )\n return mail_password_response()\n \n- security.declarePublic(\'registeredNotify\')\n+ security.declarePublic("registeredNotify")\n+\n def registeredNotify(self, new_member_id):\n # Wrapper around registeredNotify.\n- membership = getToolByName(self, \'portal_membership\')\n- utils = getToolByName(self, \'plone_utils\')\n+ membership = getToolByName(self, "portal_membership")\n+ utils = getToolByName(self, "plone_utils")\n member = membership.getMemberById(new_member_id)\n- email = member.getProperty(\'email\')\n+ email = member.getProperty("email")\n \n if member and email:\n # add the single email address\n if not utils.validateSingleEmailAddress(email):\n- raise ValueError(_(\'The email address did not validate.\'))\n+ raise ValueError(_("The email address did not validate."))\n \n try:\n checkEmailAddress(email)\n except EmailAddressInvalid:\n- raise ValueError(_(\'The email address did not validate.\'))\n+ raise ValueError(_("The email address did not validate."))\n \n- pwrt = getToolByName(self, \'portal_password_reset\')\n+ pwrt = getToolByName(self, "portal_password_reset")\n reset = pwrt.requestReset(new_member_id)\n \n # Rather than have the template try to use the mailhost, we will\n # render the message ourselves and send it from here (where we\n # don\'t need to worry about \'UseMailHost\' permissions).\n registry = getUtility(IRegistry)\n- encoding = registry.get(\'plone.email_charset\', \'utf-8\')\n+ encoding = registry.get("plone.email_charset", "utf-8")\n registered_notify_template = getMultiAdapter(\n- (self, self.REQUEST), name=\'registered_notify_template\')\n+ (self, self.REQUEST), name="registered_notify_template"\n+ )\n mail_text = registered_notify_template(\n- member=member, reset=reset, email=email, charset=encoding)\n+ member=member, reset=reset, email=email, charset=encoding\n+ )\n \n # The mail headers are not properly encoded we need to extract\n # them and let MailHost manage the encoding.\n message_obj = message_from_string(mail_text.strip())\n- subject = message_obj[\'Subject\']\n- m_to = message_obj[\'To\']\n- m_from = message_obj[\'From\']\n- msg_type = message_obj.get(\'Content-Type\', \'text/plain\')\n- host = getToolByName(self, \'MailHost\')\n- host.send(mail_text, m_to, m_from, subject=subject, charset=encoding,\n- msg_type=msg_type, immediate=True)\n+ subject = message_obj["Subject"]\n+ m_to = message_obj["To"]\n+ m_from = message_obj["From"]\n+ msg_type = message_obj.get("Content-Type", "text/plain")\n+ host = getToolByName(self, "MailHost")\n+ host.send(\n+ mail_text,\n+ m_to,\n+ m_from,\n+ subject=subject,\n+ charset=encoding,\n+ msg_type=msg_type,\n+ immediate=True,\n+ )\n \n mail_password_response = getMultiAdapter(\n- (self, self.REQUEST), name=\'mail_password_response\')\n+ (self, self.REQUEST), name="mail_password_response"\n+ )\n return mail_password_response()\n \n- security.declareProtected(ManagePortal, \'editMember\')\n+ security.declareProtected(ManagePortal, "editMember")\n \n @postonly\n @protect(CheckAuthenticator)\n- def editMember(self, member_id, properties=None, password=None,\n- roles=None, domains=None, REQUEST=None):\n- """ Edit a user\'s properties and security settings\n+ def editMember(\n+ self,\n+ member_id,\n+ properties=None,\n+ password=None,\n+ roles=None,\n+ domains=None,\n+ REQUEST=None,\n+ ):\n+ """Edit a user\'s properties and security settings\n \n o Checks should be done before this method is called using\n testPropertiesValidity and testPasswordValidity\n """\n # XXX: this method violates the rules for tools/utilities:\n # it depends on a non-utility tool\n- mtool = getToolByName(self, \'portal_membership\')\n+ mtool = getToolByName(self, "portal_membership")\n member = mtool.getMemberById(member_id)\n member.setMemberProperties(properties)\n member.setSecurityProfile(password, roles, domains)\n@@ -483,25 +509,18 @@ def editMember(self, member_id, properties=None, password=None,\n InitializeClass(RegistrationTool)\n \n _TESTS = (\n- (re.compile(r"^[0-9a-zA-Z\\.\\-\\_\\+\\\']+\\@[0-9a-zA-Z\\.\\-]+$"),\n- True, "Failed a"),\n- (re.compile(r"^[^0-9a-zA-Z]|[^0-9a-zA-Z]$"),\n- False, "Failed b"),\n- (re.compile(r"([0-9a-zA-Z_]{1})\\@."),\n- True, "Failed c"),\n- (re.compile(r".\\@([0-9a-zA-Z]{1})"),\n- True, "Failed d"),\n- (re.compile(r".\\.\\-.|.\\-\\..|.\\.\\..|.!(xn)\\-\\-."),\n- False, "Failed e"),\n- (re.compile(r".\\.\\_.|.\\-\\_.|.\\_\\..|.\\_\\-.|.\\_\\_."),\n- False, "Failed f"),\n- (re.compile(r"(.\\.([a-zA-Z]{2,}))$|(.\\.(xn--[0-9a-z]+))$"),\n- True, "Failed g"),\n+ (re.compile(r"^[0-9a-zA-Z\\.\\-\\_\\+\\\']+\\@[0-9a-zA-Z\\.\\-]+$"), True, "Failed a"),\n+ (re.compile(r"^[^0-9a-zA-Z]|[^0-9a-zA-Z]$"), False, "Failed b"),\n+ (re.compile(r"([0-9a-zA-Z_]{1})\\@."), True, "Failed c"),\n+ (re.compile(r".\\@([0-9a-zA-Z]{1})"), True, "Failed d"),\n+ (re.compile(r".\\.\\-.|.\\-\\..|.\\.\\..|.!(xn)\\-\\-."), False, "Failed e"),\n+ (re.compile(r".\\.\\_.|.\\-\\_.|.\\_\\..|.\\_\\-.|.\\_\\_."), False, "Failed f"),\n+ (re.compile(r"(.\\.([a-zA-Z]{2,}))$|(.\\.(xn--[0-9a-z]+))$"), True, "Failed g"),\n )\n \n \n class EmailAddressInvalid(ValidationError):\n- __doc__ = _(\'Invalid email address.\')\n+ __doc__ = _("Invalid email address.")\n \n \n def _checkEmail(address):\n@@ -509,26 +528,29 @@ def _checkEmail(address):\n matched = pattern.search(address) is not None\n if matched != expected:\n return False, message\n- return True, \'\'\n+ return True, ""\n \n \n # RFC 2822 local-part: dot-atom or quoted-string\n # characters allowed in atom: A-Za-z0-9!#$%&\'*+-/=?^_`{|}~\n # RFC 2821 domain: max 255 characters\n-_LOCAL_RE = re.compile(r\'([A-Za-z0-9!#$%&\\\'*+\\-/=?^_`{|}~]+\'\n- r\'(\\.[A-Za-z0-9!#$%&\\\'*+\\-/=?^_`{|}~]+)*|\'\n- r\'"[^(\\|")]*")@[^@]{3,255}$\')\n+_LOCAL_RE = re.compile(\n+ r"([A-Za-z0-9!#$%&\\\'*+\\-/=?^_`{|}~]+"\n+ r"(\\.[A-Za-z0-9!#$%&\\\'*+\\-/=?^_`{|}~]+)*|"\n+ r\'"[^(\\|")]*")@[^@]{3,255}$\'\n+)\n \n # RFC 2821 local-part: max 64 characters\n # RFC 2821 domain: sequence of dot-separated labels\n # characters allowed in label: A-Za-z0-9-, first is a letter\n # Even though the RFC does not allow it all-numeric domains do exist\n-_DOMAIN_RE = re.compile(r\'[^@]{1,64}@[A-Za-z0-9][A-Za-z0-9-]*\'\n- r\'(\\.[A-Za-z0-9][A-Za-z0-9-]*)+$\')\n+_DOMAIN_RE = re.compile(\n+ r"[^@]{1,64}@[A-Za-z0-9][A-Za-z0-9-]*" r"(\\.[A-Za-z0-9][A-Za-z0-9-]*)+$"\n+)\n \n \n def checkEmailAddress(address):\n- """ Check email address.\n+ """Check email address.\n \n This should catch most invalid but no valid addresses.\n """\ndiff --git a/Products/CMFPlone/SkinsTool.py b/Products/CMFPlone/SkinsTool.py\nindex f4ade43b53..cb35d8e587 100644\n--- a/Products/CMFPlone/SkinsTool.py\n+++ b/Products/CMFPlone/SkinsTool.py\n@@ -6,32 +6,38 @@\n \n \n class SkinsTool(PloneBaseTool, BaseTool):\n-\n- meta_type = \'Plone Skins Tool\'\n+ meta_type = "Plone Skins Tool"\n security = ClassSecurityInfo()\n- toolicon = \'skins/plone_images/skins_icon.png\'\n+ toolicon = "skins/plone_images/skins_icon.png"\n \n- default_skin = \'\'\n- request_varname = \'plone_skin\'\n+ default_skin = ""\n+ request_varname = "plone_skin"\n \n- security.declareProtected(ManagePortal, \'addSkinSelection\')\n+ security.declareProtected(ManagePortal, "addSkinSelection")\n \n def addSkinSelection(self, skinname, skinpath, test=0, make_default=0):\n # Adds a skin selection.\n- super().addSkinSelection(skinname, skinpath,\n- test=test, make_default=make_default)\n-\n- security.declareProtected(ManagePortal, \'manage_skinLayers\')\n-\n- def manage_skinLayers(self, chosen=(), add_skin=0, del_skin=0,\n- skinname=\'\', skinpath=\'\', REQUEST=None):\n- """ Change the skinLayers.\n- """\n- response = super().manage_skinLayers(chosen=chosen,\n- add_skin=add_skin, del_skin=del_skin, skinname=skinname,\n- skinpath=skinpath, REQUEST=REQUEST)\n+ super().addSkinSelection(\n+ skinname, skinpath, test=test, make_default=make_default\n+ )\n+\n+ security.declareProtected(ManagePortal, "manage_skinLayers")\n+\n+ def manage_skinLayers(\n+ self, chosen=(), add_skin=0, del_skin=0, skinname="", skinpath="", REQUEST=None\n+ ):\n+ """Change the skinLayers."""\n+ response = super().manage_skinLayers(\n+ chosen=chosen,\n+ add_skin=add_skin,\n+ del_skin=del_skin,\n+ skinname=skinname,\n+ skinpath=skinpath,\n+ REQUEST=REQUEST,\n+ )\n return response\n \n+\n SkinsTool.__doc__ = BaseTool.__doc__\n \n InitializeClass(SkinsTool)\ndiff --git a/Products/CMFPlone/TranslationServiceTool.py b/Products/CMFPlone/TranslationServiceTool.py\nindex 82854b270f..5a9f9cd77b 100644\n--- a/Products/CMFPlone/TranslationServiceTool.py\n+++ b/Products/CMFPlone/TranslationServiceTool.py\n@@ -26,78 +26,95 @@\n \n @implementer(ITranslationServiceTool)\n class TranslationServiceTool(PloneBaseTool, UniqueObject, SimpleItem):\n- """ Utility methods to access the translation machinery """\n+ """Utility methods to access the translation machinery"""\n \n- id = \'translation_service\'\n- meta_type = \'Portal Translation Service Tool\'\n- toolicon = \'skins/plone_images/site_icon.png\'\n+ id = "translation_service"\n+ meta_type = "Portal Translation Service Tool"\n+ toolicon = "skins/plone_images/site_icon.png"\n security = ClassSecurityInfo()\n \n- security.declarePublic(\'utranslate\')\n+ security.declarePublic("utranslate")\n \n def utranslate(self, *args, **kw):\n return self.translate(*args, **kw)\n \n- security.declarePublic(\'translate\')\n-\n- def translate(self, msgid, domain=None, mapping=None, context=None,\n- target_language=None, default=None):\n+ security.declarePublic("translate")\n+\n+ def translate(\n+ self,\n+ msgid,\n+ domain=None,\n+ mapping=None,\n+ context=None,\n+ target_language=None,\n+ default=None,\n+ ):\n # Translate method for resticted code like skins.\n if context is not None:\n if not IBrowserRequest.providedBy(context):\n- context = aq_get(context, \'REQUEST\', None)\n+ context = aq_get(context, "REQUEST", None)\n \n- return translate(msgid, domain=domain, mapping=mapping,\n- context=context, target_language=target_language,\n- default=default)\n+ return translate(\n+ msgid,\n+ domain=domain,\n+ mapping=mapping,\n+ context=context,\n+ target_language=target_language,\n+ default=default,\n+ )\n \n- security.declarePublic(\'encode\')\n+ security.declarePublic("encode")\n \n- def encode(self, m, input_encoding=None, output_encoding=None,\n- errors=\'strict\'):\n+ def encode(self, m, input_encoding=None, output_encoding=None, errors="strict"):\n # encode a give unicode type or string type to string type in encoding\n # output_encoding\n \n # check if input is not type unicode\n if not isinstance(m, str):\n if input_encoding is None:\n- input_encoding = \'utf-8\'\n+ input_encoding = "utf-8"\n m = str(str(m), input_encoding, errors)\n \n if output_encoding is None:\n- output_encoding = \'utf-8\'\n+ output_encoding = "utf-8"\n \n # return as type string\n return m.encode(output_encoding, errors)\n \n- security.declarePublic(\'asunicodetype\')\n+ security.declarePublic("asunicodetype")\n \n- def asunicodetype(self, m, input_encoding=None, errors=\'strict\'):\n+ def asunicodetype(self, m, input_encoding=None, errors="strict"):\n # create type unicode from type string\n \n if isinstance(m, str):\n return m\n \n if input_encoding is None:\n- input_encoding = \'utf-8\'\n+ input_encoding = "utf-8"\n \n # return as type unicode\n return str(str(m), input_encoding, errors)\n \n- security.declarePublic(\'ulocalized_time\')\n-\n- def ulocalized_time(self, time, long_format=None, time_only=None,\n- context=None, domain=\'plonelocales\', request=None):\n+ security.declarePublic("ulocalized_time")\n+\n+ def ulocalized_time(\n+ self,\n+ time,\n+ long_format=None,\n+ time_only=None,\n+ context=None,\n+ domain="plonelocales",\n+ request=None,\n+ ):\n # get some context if none is passed\n if context is None:\n context = self\n- return ulocalized_time(time, long_format, time_only,\n- context, domain, request)\n+ return ulocalized_time(time, long_format, time_only, context, domain, request)\n \n- security.declarePublic(\'day_msgid\')\n+ security.declarePublic("day_msgid")\n \n def day_msgid(self, number, format=None):\n- """ Returns the msgid which can be passed to the translation service\n+ """Returns the msgid which can be passed to the translation service\n for l10n of weekday names. Format is either None, \'a\' or \'s\'.\n \n >>> ttool = TranslationServiceTool()\n@@ -115,10 +132,10 @@ def day_msgid(self, number, format=None):\n \'weekday_wed_short\'\n """\n #\n- if format == \'s\':\n+ if format == "s":\n # short format\n method = weekdayname_msgid_short\n- elif format == \'a\':\n+ elif format == "a":\n # abbreviation\n method = weekdayname_msgid_abbr\n else:\n@@ -126,10 +143,10 @@ def day_msgid(self, number, format=None):\n method = weekdayname_msgid\n return method(number)\n \n- security.declarePublic(\'month_msgid\')\n+ security.declarePublic("month_msgid")\n \n def month_msgid(self, number, format=None):\n- """ Returns the msgid which can be passed to the translation service\n+ """Returns the msgid which can be passed to the translation service\n for l10n of month names. Format is either \'\' or \'a\' (long or\n abbreviation).\n \n@@ -144,14 +161,12 @@ def month_msgid(self, number, format=None):\n >>> ttool.month_msgid(6, format=\'a\')\n \'month_jun_abbr\'\n """\n- return \'a\' == format \\\n- and monthname_msgid_abbr(number) \\\n- or monthname_msgid(number)\n+ return "a" == format and monthname_msgid_abbr(number) or monthname_msgid(number)\n \n- security.declarePublic(\'month_english\')\n+ security.declarePublic("month_english")\n \n def month_english(self, number, format=None):\n- """ Returns the english name of month by number. Format is either \'\' or\n+ """Returns the english name of month by number. Format is either \'\' or\n \'a\' (long or abbreviation).\n \n >>> ttool = TranslationServiceTool()\n@@ -164,23 +179,23 @@ def month_english(self, number, format=None):\n """\n return monthname_english(number, format=format)\n \n- security.declarePublic(\'month\')\n+ security.declarePublic("month")\n \n def month(self, number, format=None, default=None):\n- """ Returns a Message with the month name, that can be translated by\n+ """Returns a Message with the month name, that can be translated by\n the TAL engine. Format is either None or \'a\' (long or abbreviation).\n """\n if default is None:\n default = monthname_english(number, format=format)\n- value = \'a\' == format \\\n- and monthname_msgid_abbr(number) \\\n- or monthname_msgid(number)\n+ value = (\n+ "a" == format and monthname_msgid_abbr(number) or monthname_msgid(number)\n+ )\n return PLMF(value, default=default)\n \n- security.declarePublic(\'weekday_english\')\n+ security.declarePublic("weekday_english")\n \n def weekday_english(self, number, format=None):\n- """ Returns the english name of a week by number. Format is\n+ """Returns the english name of a week by number. Format is\n either None, \'a\' or \'p\'.\n \n >>> ttool = TranslationServiceTool()\n@@ -199,4 +214,5 @@ def weekday_english(self, number, format=None):\n """\n return weekdayname_english(number, format=format)\n \n+\n InitializeClass(TranslationServiceTool)\ndiff --git a/Products/CMFPlone/TypesTool.py b/Products/CMFPlone/TypesTool.py\nindex 4a4c773db4..02d4f12a71 100644\n--- a/Products/CMFPlone/TypesTool.py\n+++ b/Products/CMFPlone/TypesTool.py\n@@ -7,12 +7,11 @@\n \n \n class TypesTool(PloneBaseTool, BaseTool):\n-\n- meta_type = \'Plone Types Tool\'\n+ meta_type = "Plone Types Tool"\n security = ClassSecurityInfo()\n- toolicon = \'skins/plone_images/document_icon.png\'\n+ toolicon = "skins/plone_images/document_icon.png"\n \n- security.declarePublic(\'listTypeTitles\')\n+ security.declarePublic("listTypeTitles")\n \n def listTypeTitles(self, container=None):\n # Return a dictionary of id/Title combinations.\n@@ -24,7 +23,7 @@ def listTypeTitles(self, container=None):\n \n return typenames\n \n- security.declarePrivate(\'listActions\')\n+ security.declarePrivate("listActions")\n \n def listActions(self, info=None, object=None, category=None):\n # List all the actions defined by a provider.\n@@ -36,22 +35,27 @@ def listActions(self, info=None, object=None, category=None):\n if type_info is not None:\n type_actions = type_info.listActions(info, object)\n if category is not None:\n- type_actions = [a for a in type_actions\n- if a.category == category]\n+ type_actions = [a for a in type_actions if a.category == category]\n actions.extend(type_actions)\n \n- if category == \'folder/add\':\n- add_actions = [ti for ti in self.values()\n- if IAction.providedBy(ti)]\n+ if category == "folder/add":\n+ add_actions = [ti for ti in self.values() if IAction.providedBy(ti)]\n actions.extend(add_actions)\n \n return actions\n \n- security.declarePublic(\'listActionInfos\')\n-\n- def listActionInfos(self, action_chain=None, object=None,\n- check_visibility=1, check_permissions=1,\n- check_condition=1, max=-1, category=None):\n+ security.declarePublic("listActionInfos")\n+\n+ def listActionInfos(\n+ self,\n+ action_chain=None,\n+ object=None,\n+ check_visibility=1,\n+ check_permissions=1,\n+ check_condition=1,\n+ max=-1,\n+ category=None,\n+ ):\n # List ActionInfo objects.\n # (method is without docstring to disable publishing)\n #\n@@ -65,28 +69,29 @@ def listActionInfos(self, action_chain=None, object=None,\n if action_chain:\n filtered_actions = []\n if isinstance(action_chain, str):\n- action_chain = (action_chain, )\n+ action_chain = (action_chain,)\n for action_ident in action_chain:\n- sep = action_ident.rfind(\'/\')\n- category, id = action_ident[:sep], action_ident[sep + 1:]\n+ sep = action_ident.rfind("/")\n+ category, id = action_ident[:sep], action_ident[sep + 1 :]\n for ai in actions:\n- if id == ai[\'id\'] and category == ai[\'category\']:\n+ if id == ai["id"] and category == ai["category"]:\n filtered_actions.append(ai)\n actions = filtered_actions\n \n action_infos = []\n for ai in actions:\n- if check_visibility and not ai[\'visible\']:\n+ if check_visibility and not ai["visible"]:\n continue\n- if check_permissions and not ai[\'allowed\']:\n+ if check_permissions and not ai["allowed"]:\n continue\n- if check_condition and not ai[\'available\']:\n+ if check_condition and not ai["available"]:\n continue\n action_infos.append(ai)\n if max + 1 and len(action_infos) >= max:\n break\n return action_infos\n \n+\n TypesTool.__doc__ = BaseTool.__doc__\n \n InitializeClass(TypesTool)\ndiff --git a/Products/CMFPlone/URLTool.py b/Products/CMFPlone/URLTool.py\nindex 87683ac434..76ccbb2f39 100644\n--- a/Products/CMFPlone/URLTool.py\n+++ b/Products/CMFPlone/URLTool.py\n@@ -10,10 +10,9 @@\n \n \n class URLTool(PloneBaseTool, BaseTool):\n-\n- meta_type = \'Plone URL Tool\'\n+ meta_type = "Plone URL Tool"\n security = ClassSecurityInfo()\n- toolicon = \'skins/plone_images/link_icon.png\'\n+ toolicon = "skins/plone_images/link_icon.png"\n \n @security.public\n def isURLInPortal(self, url, context=None):\ndiff --git a/Products/CMFPlone/UnicodeSplitter/config.py b/Products/CMFPlone/UnicodeSplitter/config.py\nindex 980053bb94..2db11d3278 100644\n--- a/Products/CMFPlone/UnicodeSplitter/config.py\n+++ b/Products/CMFPlone/UnicodeSplitter/config.py\n@@ -12,21 +12,17 @@\n rangetable = dict(\n # ascii=u"a-zA-Z0-9_",\n # digit=u"\\d",\n-\n # U+AC00-D7AF Hangul Syllables \xe3\x83\x8f\xe3\x83\xb3\xe3\x82\xb0\xe3\x83\xab\xe9\x9f\xb3\xe7\xaf\x80\xe6\x96\x87\xe5\xad\x97\n hangul="\\uAC00-\\uD7AF",\n-\n # U+30A0-30FF Katakana \xe7\x89\x87\xe4\xbb\xae\xe5\x90\x8d\n # U+3040-309F Hiragana \xe5\xb9\xb3\xe4\xbb\xae\xe5\x90\x8d\n # kana=u"\\u3040-\\u30FF",\n # hiragana=u"\\u3040-\\u309F\\u30FC",\n # katakana=u"\\u30A0-\\u30FF",\n-\n # U+4E00-9FFF CJK Unified Ideographs CJK\xe7\xb5\xb1\xe5\x90\x88\xe6\xbc\xa2\xe5\xad\x97\n # U+3400-4DBF CJK Unified Ideographs Extension A CJK\xe7\xb5\xb1\xe5\x90\x88\xe6\xbc\xa2\xe5\xad\x97\xe6\x8b\xa1\xe5\xbc\xb5A\n # U+F900-FAFF CJK Compatibility Ideographs CJK\xe4\xba\x92\xe6\x8f\x9b\xe6\xbc\xa2\xe5\xad\x97\n # ideo=u"\\u4E00-\\u9FFF\\u3400-\\u4DBF\\uF900-\\uFAFF",\n-\n cj="\\u3040-\\u30FF\\u4E00-\\u9FFF\\u3400-\\u4DBF\\uF900-\\uFAFF",\n thai="\\u0E00-\\u0E7F", # U+0E00-0E7F Thai \xe3\x82\xbf\xe3\x82\xa4\xe6\x96\x87\xe5\xad\x97\n )\n@@ -36,8 +32,7 @@\n # Splitting core.\n ps = rangetable.values()\n allp = "".join(ps)\n-glob_true = fr"[^{allp}]([^{allp}]|[\\*\\?])*|" + \\\n- "|".join([f"[{x}]+" for x in ps])\n+glob_true = rf"[^{allp}]([^{allp}]|[\\*\\?])*|" + "|".join([f"[{x}]+" for x in ps])\n \n glob_false = r"[^%s]+|" % allp + "|".join("[%s]+" % x for x in ps)\n \ndiff --git a/Products/CMFPlone/UnicodeSplitter/splitter.py b/Products/CMFPlone/UnicodeSplitter/splitter.py\nindex 22c8460e31..b78f130932 100644\n--- a/Products/CMFPlone/UnicodeSplitter/splitter.py\n+++ b/Products/CMFPlone/UnicodeSplitter/splitter.py\n@@ -20,7 +20,7 @@\n \n \n def bigram(u, limit=1):\n- """ Split into bi-gram.\n+ """Split into bi-gram.\n limit arg describes ending process.\n If limit = 0 then\n \xe6\x97\xa5\xe6\x9c\xac\xe4\xba\xba-> [\xe6\x97\xa5\xe6\x9c\xac,\xe6\x9c\xac\xe4\xba\xba, \xe4\xba\xba]\n@@ -29,10 +29,10 @@ def bigram(u, limit=1):\n \xe6\x97\xa5\xe6\x9c\xac\xe4\xba\xba-> [\xe6\x97\xa5\xe6\x9c\xac,\xe6\x9c\xac\xe4\xba\xba]\n \xe9\x87\x91 -> []\n """\n- return [u[i:i + 2] for i in range(len(u) - limit)]\n+ return [u[i : i + 2] for i in range(len(u) - limit)]\n \n \n-def process_str_post(s, enc=\'utf-8\'):\n+def process_str_post(s, enc="utf-8"):\n """Receive str, remove ? and *, then return str.\n If decode gets successful, process str as str.\n If decode gets failed, process str as ASCII.\n@@ -50,7 +50,7 @@ def process_str_post(s, enc=\'utf-8\'):\n return s.replace("?", "").replace("*", "")\n \n \n-def process_str(s, enc=\'utf-8\'):\n+def process_str(s, enc="utf-8"):\n """Receive str and encoding, then return the list\n of str as bi-grammed result.\n Decode str into str and pass it to process_unicode.\n@@ -68,7 +68,7 @@ def process_str(s, enc=\'utf-8\'):\n return [x.encode(enc, "strict") for x in bigrams]\n \n \n-def process_str_glob(s, enc=\'utf-8\'):\n+def process_str_glob(s, enc="utf-8"):\n """Receive str and encoding, then return the list\n of str considering glob processing.\n Decode str into str and pass it to process_unicode_glob.\n@@ -90,7 +90,7 @@ def process_unicode(uni):\n """Receive unicode string, then return a list of unicode\n as bi-grammed result.\n """\n- normalized = unicodedata.normalize(\'NFKC\', uni)\n+ normalized = unicodedata.normalize("NFKC", uni)\n for word in rx_U.findall(normalized):\n swords = [g.group() for g in pattern.finditer(word)]\n for sword in swords:\n@@ -104,10 +104,9 @@ def process_unicode_glob(uni):\n """Receive unicode string, then return a list of unicode\n as bi-grammed result. Considering globbing.\n """\n- normalized = unicodedata.normalize(\'NFKC\', uni)\n+ normalized = unicodedata.normalize("NFKC", uni)\n for word in rxGlob_U.findall(normalized):\n- swords = [g.group() for g in pattern_g.finditer(word)\n- if g.group() not in "*?"]\n+ swords = [g.group() for g in pattern_g.finditer(word) if g.group() not in "*?"]\n for i, sword in enumerate(swords):\n if not rx_all.match(sword[0]):\n yield sword\n@@ -125,23 +124,22 @@ def process_unicode_glob(uni):\n \n @implementer(ISplitter)\n class Splitter:\n-\n def process(self, lst):\n- """ Will be called when indexing.\n+ """Will be called when indexing.\n Receive list of str, make it bi-grammed, then return\n the list of str.\n """\n return [x for s in lst for x in process_str(s)]\n \n def processGlob(self, lst):\n- """ Will be called once when searching.\n+ """Will be called once when searching.\n Receive list of str, make it bi-grammed considering\n globbing, then return the list of str.\n """\n return [x for s in lst for x in process_str_glob(s)]\n \n def process_post_glob(self, lst):\n- """ Will be called twice when searching.\n+ """Will be called twice when searching.\n Receive list of str, Remove ? and *, then return\n the list of str.\n """\n@@ -150,8 +148,8 @@ def process_post_glob(self, lst):\n \n try:\n element_factory.registerFactory(\n- \'Word Splitter\',\n- \'Unicode Whitespace splitter\',\n+ "Word Splitter",\n+ "Unicode Whitespace splitter",\n Splitter,\n )\n except ValueError:\n@@ -160,9 +158,8 @@ def process_post_glob(self, lst):\n \n \n class CaseNormalizer:\n-\n def process(self, lst):\n- enc = \'utf-8\'\n+ enc = "utf-8"\n result = []\n for s in lst:\n # This is a hack to get the normalizer working with\n@@ -180,8 +177,8 @@ def process(self, lst):\n \n try:\n element_factory.registerFactory(\n- \'Case Normalizer\',\n- \'Unicode Case Normalizer\',\n+ "Case Normalizer",\n+ "Unicode Case Normalizer",\n CaseNormalizer,\n )\n except ValueError:\n@@ -190,9 +187,8 @@ def process(self, lst):\n \n \n class I18NNormalizer:\n-\n def process(self, lst):\n- enc = \'utf-8\'\n+ enc = "utf-8"\n result = []\n for s in lst:\n try:\n@@ -214,8 +210,8 @@ def process(self, lst):\n \n try:\n element_factory.registerFactory(\n- \'Case Normalizer\',\n- \'Unicode Ignoring Accents Case Normalizer\',\n+ "Case Normalizer",\n+ "Unicode Ignoring Accents Case Normalizer",\n I18NNormalizer,\n )\n except ValueError:\ndiff --git a/Products/CMFPlone/WorkflowTool.py b/Products/CMFPlone/WorkflowTool.py\nindex 53ab7b1732..1ee1f15d0d 100644\n--- a/Products/CMFPlone/WorkflowTool.py\n+++ b/Products/CMFPlone/WorkflowTool.py\n@@ -15,30 +15,35 @@\n \n \n try:\n- pkg_resources.get_distribution(\'plone.app.multilingual\')\n+ pkg_resources.get_distribution("plone.app.multilingual")\n except pkg_resources.DistributionNotFound:\n has_new_lang_bypass = False\n else:\n- has_new_lang_bypass = int(pkg_resources.get_distribution(\n- \'plone.app.multilingual\').version.split(\'.\')[0]) > 1\n+ has_new_lang_bypass = (\n+ int(\n+ pkg_resources.get_distribution("plone.app.multilingual").version.split(".")[\n+ 0\n+ ]\n+ )\n+ > 1\n+ )\n \n \n class WorkflowTool(PloneBaseTool, BaseTool):\n-\n- meta_type = \'Plone Workflow Tool\'\n+ meta_type = "Plone Workflow Tool"\n security = ClassSecurityInfo()\n plone_tool = 1\n- toolicon = \'skins/plone_images/workflow_icon.png\'\n+ toolicon = "skins/plone_images/workflow_icon.png"\n \n # TODO this should not make it into 1.0\n # Refactor me, my maker was tired\n def flattenTransitions(self, objs, container=None):\n # This is really hokey - hold on!!\n- if hasattr(objs, \'startswith\'):\n+ if hasattr(objs, "startswith"):\n return ()\n \n # TODO Need to behave differently for paths\n- if len(objs) and \'/\' in objs[0]:\n+ if len(objs) and "/" in objs[0]:\n return self.flattenTransitionsForPaths(objs)\n transitions = []\n t_names = []\n@@ -55,20 +60,20 @@ def flattenTransitions(self, objs, container=None):\n pass\n if trans:\n for t in trans:\n- if t[\'name\'] not in t_names:\n+ if t["name"] not in t_names:\n transitions.append(t)\n- t_names.append(t[\'name\'])\n+ t_names.append(t["name"])\n \n return tuple(transitions[:])\n \n def flattenTransitionsForPaths(self, paths):\n # This is even more hokey!!\n- if hasattr(paths, \'startswith\'):\n+ if hasattr(paths, "startswith"):\n return ()\n \n transitions = []\n t_names = []\n- portal = getToolByName(self, \'portal_url\').getPortalObject()\n+ portal = getToolByName(self, "portal_url").getPortalObject()\n \n for o in [portal.restrictedTraverse(path) for path in paths]:\n trans = ()\n@@ -80,13 +85,13 @@ def flattenTransitionsForPaths(self, paths):\n pass\n if trans:\n for t in trans:\n- if t[\'name\'] not in t_names:\n+ if t["name"] not in t_names:\n transitions.append(t)\n- t_names.append(t[\'name\'])\n+ t_names.append(t["name"])\n \n return tuple(transitions[:])\n \n- security.declarePublic(\'getTransitionsFor\')\n+ security.declarePublic("getTransitionsFor")\n \n def getTransitionsFor(self, obj=None, container=None, REQUEST=None):\n if type(obj) is type([]):\n@@ -100,21 +105,26 @@ def getTransitionsFor(self, obj=None, container=None, REQUEST=None):\n if sdef is not None:\n for tid in sdef.transitions:\n tdef = wf.transitions.get(tid, None)\n- if tdef is not None and \\\n- tdef.trigger_type == TRIGGER_USER_ACTION and \\\n- tdef.actbox_name and \\\n- wf._checkTransitionGuard(tdef, obj) and \\\n- not tdef.id in result:\n+ if (\n+ tdef is not None\n+ and tdef.trigger_type == TRIGGER_USER_ACTION\n+ and tdef.actbox_name\n+ and wf._checkTransitionGuard(tdef, obj)\n+ and not tdef.id in result\n+ ):\n result[tdef.id] = {\n- \'id\': tdef.id,\n- \'title\': tdef.title,\n- \'title_or_id\': tdef.title_or_id(),\n- \'description\': tdef.description,\n- \'name\': tdef.actbox_name,\n- \'url\': tdef.actbox_url %\n- {\'content_url\': obj.absolute_url(),\n- \'portal_url\': \'\',\n- \'folder_url\': \'\'}}\n+ "id": tdef.id,\n+ "title": tdef.title,\n+ "title_or_id": tdef.title_or_id(),\n+ "description": tdef.description,\n+ "name": tdef.actbox_name,\n+ "url": tdef.actbox_url\n+ % {\n+ "content_url": obj.absolute_url(),\n+ "portal_url": "",\n+ "folder_url": "",\n+ },\n+ }\n return tuple(result.values())\n \n def workflows_in_use(self):\n@@ -130,7 +140,7 @@ def workflows_in_use(self):\n \n return tuple(in_use[:])\n \n- security.declarePublic(\'getWorklists\')\n+ security.declarePublic("getWorklists")\n \n def getWorklists(self):\n # Instead of manually scraping actions_box, let\'s\n@@ -147,7 +157,7 @@ def getWorklists(self):\n # We want to know which types use the workflows with worklists\n # This for example avoids displaying \'pending\' of multiple workflows in\n # the same worklist\n- types_tool = getToolByName(self, \'portal_types\')\n+ types_tool = getToolByName(self, "portal_types")\n list_ptypes = types_tool.listContentTypes()\n types_by_wf = {} # wf:[list,of,types]\n for t in list_ptypes:\n@@ -155,7 +165,7 @@ def getWorklists(self):\n types_by_wf[wf] = types_by_wf.get(wf, []) + [t]\n \n # Placeful stuff\n- placeful_tool = getToolByName(self, \'portal_placeful_workflow\', None)\n+ placeful_tool = getToolByName(self, "portal_placeful_workflow", None)\n if placeful_tool is not None:\n for policy in placeful_tool.getWorkflowPolicies():\n for t in list_ptypes:\n@@ -169,7 +179,7 @@ def getWorklists(self):\n # into 1 sequence\n \n wf = self.getWorkflowById(id)\n- if hasattr(wf, \'worklists\'):\n+ if hasattr(wf, "worklists"):\n wlists = []\n for worklist in wf.worklists:\n wlist_def = wf.worklists[worklist]\n@@ -180,14 +190,15 @@ def getWorklists(self):\n var_matches[key] = wlist_def.var_matches[key]\n \n a_wlist = {\n- \'id\': worklist,\n- \'guard\': wlist_def.getGuard(),\n- \'guard_permissions\': wlist_def.getGuard().permissions,\n- \'guard_roles\': wlist_def.getGuard().roles,\n- \'catalog_vars\': var_matches,\n- \'name\': getattr(wlist_def, \'actbox_name\', None),\n- \'url\': getattr(wlist_def, \'actbox_url\', None),\n- \'types\': types_by_wf.get(id, [])}\n+ "id": worklist,\n+ "guard": wlist_def.getGuard(),\n+ "guard_permissions": wlist_def.getGuard().permissions,\n+ "guard_roles": wlist_def.getGuard().roles,\n+ "catalog_vars": var_matches,\n+ "name": getattr(wlist_def, "actbox_name", None),\n+ "url": getattr(wlist_def, "actbox_url", None),\n+ "types": types_by_wf.get(id, []),\n+ }\n wlists.append(a_wlist)\n # yes, we can duplicates, we filter duplicates out on the\n # calling PyhtonScript client\n@@ -195,7 +206,7 @@ def getWorklists(self):\n \n return wf_with_wlists\n \n- security.declarePublic(\'getWorklistsResults\')\n+ security.declarePublic("getWorklistsResults")\n \n def getWorklistsResults(self):\n # Return all the objects concerned by one or more worklists.\n@@ -208,8 +219,8 @@ def getWorklistsResults(self):\n # We want to know which types use the workflows with worklists\n # This for example avoids displaying \'pending\' of multiple workflows in\n # the same worklist\n- types_tool = getToolByName(self, \'portal_types\')\n- catalog = getToolByName(self, \'portal_catalog\')\n+ types_tool = getToolByName(self, "portal_types")\n+ catalog = getToolByName(self, "portal_catalog")\n \n list_ptypes = types_tool.listContentTypes()\n types_by_wf = {} # wf:[list,of,types]\n@@ -218,7 +229,7 @@ def getWorklistsResults(self):\n types_by_wf[wf] = types_by_wf.get(wf, []) + [t]\n \n # PlacefulWorkflowTool will give us other results\n- placeful_tool = getToolByName(self, \'portal_placeful_workflow\', None)\n+ placeful_tool = getToolByName(self, "portal_placeful_workflow", None)\n if placeful_tool is not None:\n for policy in placeful_tool.getWorkflowPolicies():\n for t in list_ptypes:\n@@ -229,7 +240,7 @@ def getWorklistsResults(self):\n objects_by_path = {}\n for id in self.getWorkflowIds():\n wf = self.getWorkflowById(id)\n- if hasattr(wf, \'worklists\'):\n+ if hasattr(wf, "worklists"):\n for worklist in wf.worklists:\n wlist_def = wf.worklists[worklist]\n # Make the var_matches a dict instead of PersistentMapping\n@@ -239,20 +250,22 @@ def getWorklistsResults(self):\n catalog_vars[key] = wlist_def.var_matches[key]\n # Support LinguaPlone review situations, you want to see\n # content in *all* languages\n- if \'Language\' not in catalog_vars:\n+ if "Language" not in catalog_vars:\n if has_new_lang_bypass:\n- catalog_vars[\'path\'] = \'/\'\n+ catalog_vars["path"] = "/"\n else:\n- catalog_vars[\'Language\'] = \'all\'\n+ catalog_vars["Language"] = "all"\n # Include inactive content in result list. This is\n # especially important for content scheduled to go public\n # in the future, but needs to be reviewed before this.\n- catalog_vars[\'show_inactive\'] = True\n+ catalog_vars["show_inactive"] = True\n for result in catalog.searchResults(catalog_vars):\n o = result.getObject()\n- if o \\\n- and id in self.getChainFor(o) \\\n- and wlist_def.getGuard().check(sm, wf, o):\n+ if (\n+ o\n+ and id in self.getChainFor(o)\n+ and wlist_def.getGuard().check(sm, wf, o)\n+ ):\n absurl = o.absolute_url()\n if absurl:\n objects_by_path[absurl] = (o.modified(), o)\n@@ -260,7 +273,7 @@ def getWorklistsResults(self):\n results = objects_by_path.values()\n return tuple(obj[1] for obj in sorted(results))\n \n- security.declareProtected(ManagePortal, \'getChainForPortalType\')\n+ security.declareProtected(ManagePortal, "getChainForPortalType")\n \n def getChainForPortalType(self, pt_name, managescreen=0):\n # Get a chain for a specific portal type.\n@@ -269,18 +282,18 @@ def getChainForPortalType(self, pt_name, managescreen=0):\n else:\n # (Default) is _not_ a chain nor a workflow in a chain.\n if managescreen:\n- return \'(Default)\'\n+ return "(Default)"\n else:\n # Return the default chain.\n return self._default_chain\n \n- security.declareProtected(ManagePortal, \'listWorkflows\')\n+ security.declareProtected(ManagePortal, "listWorkflows")\n \n def listWorkflows(self):\n # Return the list of workflows.\n return self.keys()\n \n- security.declarePublic(\'getTitleForStateOnType\')\n+ security.declarePublic("getTitleForStateOnType")\n \n def getTitleForStateOnType(self, state_name, p_type):\n # Returns the workflow state title for a given state name,\n@@ -293,11 +306,10 @@ def getTitleForStateOnType(self, state_name, p_type):\n states = wf.states\n state = getattr(states, state_name, None)\n if state is not None:\n- return getattr(aq_base(state), \'title\', None) \\\n- or state_name\n+ return getattr(aq_base(state), "title", None) or state_name\n return state_name\n \n- security.declarePublic(\'getTitleForTransitionOnType\')\n+ security.declarePublic("getTitleForTransitionOnType")\n \n def getTitleForTransitionOnType(self, trans_name, p_type):\n # Returns the workflow transition title for a given transition name,\n@@ -310,11 +322,12 @@ def getTitleForTransitionOnType(self, trans_name, p_type):\n transitions = wf.transitions\n trans = getattr(transitions, trans_name, None)\n if trans is not None:\n- return getattr(aq_base(trans), \'actbox_name\', None) \\\n- or trans_name\n+ return (\n+ getattr(aq_base(trans), "actbox_name", None) or trans_name\n+ )\n return trans_name\n \n- security.declarePublic(\'listWFStatesByTitle\')\n+ security.declarePublic("listWFStatesByTitle")\n \n def listWFStatesByTitle(self, filter_similar=False):\n # Returns the states of all available workflows, optionally filtering\n@@ -322,13 +335,13 @@ def listWFStatesByTitle(self, filter_similar=False):\n states = []\n dup_list = {}\n for wf in self.values():\n- state_folder = getattr(wf, \'states\', None)\n+ state_folder = getattr(wf, "states", None)\n if state_folder is not None:\n if not filter_similar:\n states.extend(state_folder.values())\n else:\n for state in state_folder.values():\n- key = f\'{state.id}:{state.title}\'\n+ key = f"{state.id}:{state.title}"\n if not key in dup_list:\n states.append(state)\n dup_list[key] = 1\n@@ -341,10 +354,10 @@ def getChainFor(self, ob):\n # the portal_type.\n return getMultiAdapter((ob, self), IWorkflowChain)\n \n- security.declarePrivate(\'listActions\')\n+ security.declarePrivate("listActions")\n \n def listActions(self, info=None, object=None):\n- """ Returns a list of actions to be displayed to the user.\n+ """Returns a list of actions to be displayed to the user.\n \n o Invoked by the portal_actions tool.\n \ndiff --git a/Products/CMFPlone/__init__.py b/Products/CMFPlone/__init__.py\nindex 4edd033abe..245b8bbd44 100644\n--- a/Products/CMFPlone/__init__.py\n+++ b/Products/CMFPlone/__init__.py\n@@ -34,7 +34,6 @@\n \n \n def initialize(context):\n-\n # Stuff has been moved from module level to this method for a\n # better separation of import and installation.\n # For the general user this change does not make a difference.\ndiff --git a/Products/CMFPlone/bbb.py b/Products/CMFPlone/bbb.py\nindex c92083cb24..c359ab86f2 100644\n--- a/Products/CMFPlone/bbb.py\n+++ b/Products/CMFPlone/bbb.py\n@@ -3,7 +3,7 @@\n \n HAS_ZSERVER = True\n try:\n- dist = pkg_resources.get_distribution(\'ZServer\')\n+ dist = pkg_resources.get_distribution("ZServer")\n except pkg_resources.DistributionNotFound:\n HAS_ZSERVER = False\n \ndiff --git a/Products/CMFPlone/browser/admin.py b/Products/CMFPlone/browser/admin.py\nindex 98d4a3256c..f687ede690 100644\n--- a/Products/CMFPlone/browser/admin.py\n+++ b/Products/CMFPlone/browser/admin.py\n@@ -43,16 +43,17 @@\n HAS_VOLTO = True\n except pkg_resources.DistributionNotFound:\n HAS_VOLTO = False\n-LOGGER = logging.getLogger(\'Products.CMFPlone\')\n+LOGGER = logging.getLogger("Products.CMFPlone")\n \n \n class AppTraverser(DefaultPublishTraverse):\n adapts(IApplication, IRequest)\n \n def publishTraverse(self, request, name):\n- if name == \'index_html\':\n+ if name == "index_html":\n view = queryMultiAdapter(\n- (self.context, request), Interface, \'plone-overview\')\n+ (self.context, request), Interface, "plone-overview"\n+ )\n if view is not None:\n return view\n return DefaultPublishTraverse.publishTraverse(self, request, name)\n@@ -67,25 +68,22 @@ def sites(self, root=None):\n \n result = []\n secman = getSecurityManager()\n- candidates = (\n- obj for obj in root.values() if not isinstance(obj, Broken)\n- )\n+ candidates = (obj for obj in root.values() if not isinstance(obj, Broken))\n for obj in candidates:\n- if obj.meta_type == \'Folder\':\n+ if obj.meta_type == "Folder":\n result = result + self.sites(obj)\n elif IPloneSiteRoot.providedBy(obj):\n if secman.checkPermission(View, obj):\n result.append(obj)\n- elif obj.getId() in getattr(root, \'_mount_points\', {}):\n+ elif obj.getId() in getattr(root, "_mount_points", {}):\n result.extend(self.sites(root=obj))\n return result\n \n def outdated(self, obj):\n # Try to pick the portal_migration as an attribute\n # (Plone 5 unmigrated site root) or as an item\n- mig = (\n- getattr(obj, "portal_migration", None)\n- or obj.get(\'portal_migration\', None)\n+ mig = getattr(obj, "portal_migration", None) or obj.get(\n+ "portal_migration", None\n )\n if mig is not None:\n return mig.needUpgrading()\n@@ -99,13 +97,13 @@ def upgrade_url(self, site, can_manage=None):\n if can_manage is None:\n can_manage = self.can_manage()\n if can_manage:\n- return site.absolute_url() + \'/@@plone-upgrade\'\n+ return site.absolute_url() + "/@@plone-upgrade"\n else:\n- return self.context.absolute_url() + \'/@@plone-root-login\'\n+ return self.context.absolute_url() + "/@@plone-root-login"\n \n \n class RootLoginRedirect(BrowserView):\n- """ @@plone-root-login\n+ """@@plone-root-login\n \n This view of the Zope root forces authentication via the root\n acl_users and then redirects elsewhere.\n@@ -119,7 +117,8 @@ def __call__(self, came_from=None):\n # Note: \'\\\\domain.org\' is not recognised as host,\n # which is good.\n came_from = parse.urljoin(\n- self.context.absolute_url() + \'/\', came_from,\n+ self.context.absolute_url() + "/",\n+ came_from,\n )\n elif not came_from.startswith(self.context.absolute_url()):\n # Note: we cannot use portal_url.isURLInPortal here, because we\n@@ -131,43 +130,41 @@ def __call__(self, came_from=None):\n \n \n class RootLogout(BrowserView):\n- """ @@plone-root-logout """\n+ """@@plone-root-logout"""\n \n- logout = ViewPageTemplateFile(\'templates/plone-admin-logged-out.pt\')\n+ logout = ViewPageTemplateFile("templates/plone-admin-logged-out.pt")\n \n def __call__(self):\n response = self.request.response\n realm = response.realm\n response.setStatus(401)\n- response.setHeader(\'WWW-Authenticate\', \'basic realm="%s"\' % realm, 1)\n+ response.setHeader("WWW-Authenticate", \'basic realm="%s"\' % realm, 1)\n response.setBody(self.logout())\n return\n \n \n class FrontPage(BrowserView):\n-\n- index = ViewPageTemplateFile(\'templates/plone-frontpage.pt\')\n+ index = ViewPageTemplateFile("templates/plone-frontpage.pt")\n \n \n class AddPloneSite(BrowserView):\n-\n # Profiles that are installed by default,\n # but can be removed later.\n default_extension_profiles = (\n- \'plone.app.caching:default\',\n- \'plonetheme.barceloneta:default\',\n+ "plone.app.caching:default",\n+ "plonetheme.barceloneta:default",\n )\n # Let\'s have a separate list for Volto.\n volto_default_extension_profiles = (\n- \'plone.app.caching:default\',\n- \'plonetheme.barceloneta:default\',\n- \'plone.volto:default\',\n+ "plone.app.caching:default",\n+ "plonetheme.barceloneta:default",\n+ "plone.volto:default",\n )\n \n def profiles(self):\n base_profiles = []\n extension_profiles = []\n- if HAS_VOLTO and not self.request.get(\'classic\'):\n+ if HAS_VOLTO and not self.request.get("classic"):\n selected_extension_profiles = self.volto_default_extension_profiles\n else:\n selected_extension_profiles = self.default_extension_profiles\n@@ -175,30 +172,32 @@ def profiles(self):\n # profiles available for install/uninstall, but hidden at the time\n # the Plone site is created\n not_installable = [\n- \'Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow\',\n+ "Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow",\n ]\n utils = getAllUtilitiesRegisteredFor(INonInstallable)\n for util in utils:\n not_installable.extend(util.getNonInstallableProfiles())\n \n for info in profile_registry.listProfileInfo():\n- if info.get(\'type\') == EXTENSION and \\\n- info.get(\'for\') in (IPloneSiteRoot, None):\n- profile_id = info.get(\'id\')\n+ if info.get("type") == EXTENSION and info.get("for") in (\n+ IPloneSiteRoot,\n+ None,\n+ ):\n+ profile_id = info.get("id")\n if profile_id not in not_installable:\n if profile_id in selected_extension_profiles:\n- info[\'selected\'] = \'selected\'\n+ info["selected"] = "selected"\n extension_profiles.append(info)\n \n def _key(v):\n # Make sure implicitly selected items come first\n- selected = v.get(\'selected\') and \'automatic\' or \'manual\'\n- return \'{}-{}\'.format(selected, v.get(\'title\', \'\'))\n+ selected = v.get("selected") and "automatic" or "manual"\n+ return "{}-{}".format(selected, v.get("title", ""))\n+\n extension_profiles.sort(key=_key)\n \n for info in profile_registry.listProfileInfo():\n- if info.get(\'type\') == BASE and \\\n- info.get(\'for\') in (IPloneSiteRoot, None):\n+ if info.get("type") == BASE and info.get("for") in (IPloneSiteRoot, None):\n base_profiles.append(info)\n \n return dict(\n@@ -208,25 +207,25 @@ def _key(v):\n )\n \n def browser_language(self):\n- language = \'en\'\n+ language = "en"\n pl = IUserPreferredLanguages(self.request)\n if pl is not None:\n languages = pl.getPreferredLanguages()\n for httplang in languages:\n- parts = (httplang.split(\'-\') + [None, None])[:3]\n+ parts = (httplang.split("-") + [None, None])[:3]\n if parts[0] == parts[1]:\n # Avoid creating a country code for simple languages codes\n parts = [parts[0], None, None]\n try:\n locale = locales.getLocale(*parts)\n- language = locale.getLocaleID().replace(\'_\', \'-\').lower()\n+ language = locale.getLocaleID().replace("_", "-").lower()\n break\n except LoadLocaleError:\n # Just try the next combination\n pass\n return language\n \n- def grouped_languages(self, default=\'en\'):\n+ def grouped_languages(self, default="en"):\n util = queryUtility(IContentLanguageAvailability)\n available = util.getLanguages(combined=True)\n languages = dict(util.getLanguageListing())\n@@ -234,41 +233,43 @@ def grouped_languages(self, default=\'en\'):\n # Group country specific versions by language\n grouped = OrderedDict()\n for langcode, data in available.items():\n- lang = langcode.split(\'-\')[0]\n+ lang = langcode.split("-")[0]\n language = languages.get(lang, lang) # Label\n \n- struct = grouped.get(lang, {\'label\': language, \'languages\': []})\n+ struct = grouped.get(lang, {"label": language, "languages": []})\n \n- langs = struct[\'languages\']\n- langs.append({\n- \'langcode\': langcode,\n- \'label\': data.get(\'native\', data.get(\'name\')),\n- })\n+ langs = struct["languages"]\n+ langs.append(\n+ {\n+ "langcode": langcode,\n+ "label": data.get("native", data.get("name")),\n+ }\n+ )\n \n grouped[lang] = struct\n \n # Sort list by language, next by country\n- data = sorted(grouped.values(), key=lambda k: k[\'label\'])\n+ data = sorted(grouped.values(), key=lambda k: k["label"])\n for item in data:\n- item[\'languages\'] = sorted(\n- item[\'languages\'], key=lambda k: k[\'label\'].lower())\n+ item["languages"] = sorted(\n+ item["languages"], key=lambda k: k["label"].lower()\n+ )\n return data\n \n def timezones(self):\n tz_vocab = getUtility(\n- IVocabularyFactory,\n- \'plone.app.vocabularies.CommonTimezones\'\n+ IVocabularyFactory, "plone.app.vocabularies.CommonTimezones"\n )(self.context)\n \n grouped = OrderedDict()\n tz_values = [it.value for it in tz_vocab]\n for value in tz_values:\n- splitted = value.split(\'/\')\n+ splitted = value.split("/")\n group = splitted.pop(0)\n- label = \'/\'.join(splitted)\n+ label = "/".join(splitted)\n \n entries = grouped.get(group, [])\n- entries.append({\'label\': label or group, \'value\': value})\n+ entries.append({"label": label or group, "value": value})\n grouped[group] = entries\n \n return grouped\n@@ -276,9 +277,9 @@ def timezones(self):\n def __call__(self):\n context = self.context\n form = self.request.form\n- submitted = form.get(\'form.submitted\', False)\n+ submitted = form.get("form.submitted", False)\n if submitted:\n- site_id = form.get(\'site_id\', \'Plone\')\n+ site_id = form.get("site_id", "Plone")\n \n # CSRF protect. DO NOT use auto CSRF protection for adding a site\n alsoProvides(self.request, IDisableCSRFProtection)\n@@ -287,57 +288,56 @@ def __call__(self):\n # if it is because it is not installed until a plone site\n # is created\n if queryUtility(IKeyManager) is None:\n- LOGGER.info(\'CSRF protection disabled on initial site \'\n- \'creation\')\n+ LOGGER.info("CSRF protection disabled on initial site " "creation")\n else:\n # we have a keymanager, check csrf protection manually now\n checkCSRF(self.request)\n \n site = addPloneSite(\n- context, site_id,\n- title=form.get(\'title\', \'\'),\n- profile_id=form.get(\'profile_id\', _DEFAULT_PROFILE),\n- extension_ids=form.get(\'extension_ids\', ()),\n- setup_content=form.get(\'setup_content\', False),\n- default_language=form.get(\'default_language\', \'en\'),\n- portal_timezone=form.get(\'portal_timezone\', \'UTC\')\n+ context,\n+ site_id,\n+ title=form.get("title", ""),\n+ profile_id=form.get("profile_id", _DEFAULT_PROFILE),\n+ extension_ids=form.get("extension_ids", ()),\n+ setup_content=form.get("setup_content", False),\n+ default_language=form.get("default_language", "en"),\n+ portal_timezone=form.get("portal_timezone", "UTC"),\n )\n self.request.response.redirect(site.absolute_url())\n- return \'\'\n+ return ""\n \n return self.index()\n \n \n class Upgrade(BrowserView):\n-\n def upgrades(self):\n- pm = getattr(self.context, \'portal_migration\')\n+ pm = getattr(self.context, "portal_migration")\n return pm.listUpgrades()\n \n def versions(self):\n- pm = getattr(self.context, \'portal_migration\')\n+ pm = getattr(self.context, "portal_migration")\n result = {}\n- result[\'instance\'] = pm.getInstanceVersion()\n- result[\'fs\'] = pm.getFileSystemVersion()\n- result[\'equal\'] = result[\'instance\'] == result[\'fs\']\n- instance_version = normalize_version(result[\'instance\'])\n- fs_version = normalize_version(result[\'fs\'])\n- result[\'instance_gt\'] = instance_version > fs_version\n- result[\'instance_lt\'] = instance_version < fs_version\n- result[\'corelist\'] = pm.coreVersions()\n+ result["instance"] = pm.getInstanceVersion()\n+ result["fs"] = pm.getFileSystemVersion()\n+ result["equal"] = result["instance"] == result["fs"]\n+ instance_version = normalize_version(result["instance"])\n+ fs_version = normalize_version(result["fs"])\n+ result["instance_gt"] = instance_version > fs_version\n+ result["instance_lt"] = instance_version < fs_version\n+ result["corelist"] = pm.coreVersions()\n return result\n \n def __call__(self):\n form = self.request.form\n- submitted = form.get(\'form.submitted\', False)\n+ submitted = form.get("form.submitted", False)\n if submitted:\n # CSRF protect. DO NOT use auto CSRF protection for upgrading sites\n alsoProvides(self.request, IDisableCSRFProtection)\n \n- pm = getattr(self.context, \'portal_migration\')\n+ pm = getattr(self.context, "portal_migration")\n report = pm.upgrade(\n REQUEST=self.request,\n- dry_run=form.get(\'dry_run\', False),\n+ dry_run=form.get("dry_run", False),\n )\n return self.index(\n report=report,\n@@ -348,7 +348,7 @@ def __call__(self):\n def can_migrate_to_volto(self):\n if not HAS_VOLTO:\n return False\n- pm = getattr(self.context, \'portal_migration\')\n+ pm = getattr(self.context, "portal_migration")\n if pm.getInstanceVersion() < "6005":\n return False\n try:\ndiff --git a/Products/CMFPlone/browser/atd.py b/Products/CMFPlone/browser/atd.py\nindex 161c430f33..166c368d43 100644\n--- a/Products/CMFPlone/browser/atd.py\n+++ b/Products/CMFPlone/browser/atd.py\n@@ -9,22 +9,20 @@\n \n @implementer(IATDProxyView)\n class ATDProxyView:\n- """ Proxy for the \'After the Deadline\' spellchecker\n- """\n+ """Proxy for the \'After the Deadline\' spellchecker"""\n \n def checkDocument(self):\n- """ Proxy for the AtD service\'s checkDocument function\n- See http://www.afterthedeadline.com/api.slp for more info.\n+ """Proxy for the AtD service\'s checkDocument function\n+ See http://www.afterthedeadline.com/api.slp for more info.\n """\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(\n- ITinyMCESchema, prefix="plone", check=False)\n- if settings.libraries_spellchecker_choice != \'AtD\':\n- return \'atd not enabled\'\n+ settings = registry.forInterface(ITinyMCESchema, prefix="plone", check=False)\n+ if settings.libraries_spellchecker_choice != "AtD":\n+ return "atd not enabled"\n \n tool = getToolByName(self.context, "portal_membership")\n if bool(tool.isAnonymousUser()):\n- return \'must be authenticated to use atd\'\n+ return "must be authenticated to use atd"\n \n data = self.request._file.read()\n service_url = settings.libraries_atd_service_url\n@@ -35,13 +33,12 @@ def checkDocument(self):\n \n if response.status != http_client.OK:\n service.close()\n- raise Exception(\'Unexpected response code from AtD service %d\' %\n- response.status)\n+ raise Exception(\n+ "Unexpected response code from AtD service %d" % response.status\n+ )\n \n- self.request.RESPONSE.setHeader(\'content-type\',\n- \'text/xml;charset=utf-8\')\n+ self.request.RESPONSE.setHeader("content-type", "text/xml;charset=utf-8")\n respxml = response.read()\n service.close()\n- xml = respxml.strip().replace("\\r", \'\').replace("\\n", \'\').replace(\n- \'> \', \'>\')\n+ xml = respxml.strip().replace("\\r", "").replace("\\n", "").replace("> ", ">")\n return xml\ndiff --git a/Products/CMFPlone/browser/author.py b/Products/CMFPlone/browser/author.py\nindex 741d365606..ed13dd4e98 100644\n--- a/Products/CMFPlone/browser/author.py\n+++ b/Products/CMFPlone/browser/author.py\n@@ -28,85 +28,83 @@\n \n \n class AuthorFeedbackForm(form.Form):\n-\n fields = field.Fields(IAuthorFeedbackForm)\n ignoreContext = True\n \n- @button.buttonAndHandler(_(\'label_send\', default=\'Send\'),\n- name=\'send\')\n+ @button.buttonAndHandler(_("label_send", default="Send"), name="send")\n def handle_send(self, action):\n self.portal_state = getMultiAdapter(\n- (self.context, self.request),\n- name=\'plone_portal_state\'\n+ (self.context, self.request), name="plone_portal_state"\n )\n \n self.portal = self.portal_state.portal()\n- self.membership_tool = getToolByName(\n- self.context, \'portal_membership\'\n- )\n+ self.membership_tool = getToolByName(self.context, "portal_membership")\n \n self.feedback_template = self.context.restrictedTraverse(\n- \'@@author-feedback-template\'\n+ "@@author-feedback-template"\n )\n \n data, errors = self.extractData()\n if errors:\n IStatusMessage(self.request).addStatusMessage(\n- self.formErrorsMessage,\n- type=\'error\'\n+ self.formErrorsMessage, type="error"\n )\n \n return\n \n- referer = data.get(\'referer\', \'unknown referer\')\n- subject = data.get(\'subject\', \'\')\n- message = data.get(\'message\', \'\')\n+ referer = data.get("referer", "unknown referer")\n+ subject = data.get("subject", "")\n+ message = data.get("message", "")\n # Author is None means portal administrator\n- author = data.get(\'author\', None)\n+ author = data.get("author", None)\n \n sender = self.portal_state.member()\n registry = getUtility(IRegistry)\n- mail_settings = registry.forInterface(IMailSchema, prefix=\'plone\')\n+ mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n envelope_from = mail_settings.email_from_address\n \n if author is None:\n send_to_address = mail_settings.email_from_address\n else:\n author_member = self.membership_tool.getMemberById(author)\n- send_to_address = author_member.getProperty(\'email\')\n+ send_to_address = author_member.getProperty("email")\n \n- send_from_address = sender.getProperty(\'email\')\n+ send_from_address = sender.getProperty("email")\n \n- if send_from_address == \'\':\n+ if send_from_address == "":\n IStatusMessage(self.request).addStatusMessage(\n- _(\'Could not find a valid email address\'),\n- type=\'error\'\n+ _("Could not find a valid email address"), type="error"\n )\n return\n \n sender_id = "{} ({}), {}".format(\n- sender.getProperty(\'fullname\'),\n- sender.getId(),\n- send_from_address\n+ sender.getProperty("fullname"), sender.getId(), send_from_address\n )\n \n mail_host = getUtility(IMailHost)\n registry = getUtility(IRegistry)\n- email_charset = registry.get(\'plone.email_charset\', \'utf-8\')\n+ email_charset = registry.get("plone.email_charset", "utf-8")\n \n try:\n message = self.feedback_template(\n- self, send_from_address=send_from_address,\n- sender_id=sender_id, url=referer, subject=subject,\n- message=message, encoding=email_charset,\n- email_from_name=mail_settings.email_from_name\n+ self,\n+ send_from_address=send_from_address,\n+ sender_id=sender_id,\n+ url=referer,\n+ subject=subject,\n+ message=message,\n+ encoding=email_charset,\n+ email_from_name=mail_settings.email_from_name,\n )\n \n message = message.encode(email_charset)\n \n mail_host.send(\n- message, send_to_address, envelope_from,\n- subject=subject, charset=email_charset\n+ message,\n+ send_to_address,\n+ envelope_from,\n+ subject=subject,\n+ charset=email_charset,\n )\n except ConflictError:\n raise\n@@ -114,32 +112,27 @@ def handle_send(self, action):\n logger.info("Unable to send mail: " + str(e))\n \n IStatusMessage(self.request).addStatusMessage(\n- _(\'Unable to send mail.\'),\n- type=\'error\'\n+ _("Unable to send mail."), type="error"\n )\n \n return\n \n- IStatusMessage(self.request).addStatusMessage(\n- _(\'Mail sent.\'),\n- type=\'info\'\n+ IStatusMessage(self.request).addStatusMessage(_("Mail sent."), type="info")\n+ self.request.response.redirect(\n+ "{}/author/{}".format(self.portal.absolute_url(), author or "")\n )\n- self.request.response.redirect(\'{}/author/{}\'.format(\n- self.portal.absolute_url(),\n- author or \'\'))\n return\n \n \n @implementer(IPublishTraverse)\n class AuthorView(BrowserView):\n-\n def __init__(self, context, request):\n super().__init__(context, request)\n \n self.username = None\n \n def publishTraverse(self, request, name):\n- request[\'TraversalRequestNameStack\'] = []\n+ request["TraversalRequestNameStack"] = []\n \n self.username = name\n return self\n@@ -166,46 +159,37 @@ def author(self):\n if not authorinfo or not portrait:\n return {}\n \n- return {\n- \'info\': authorinfo,\n- \'portrait\': portrait\n- }\n+ return {"info": authorinfo, "portrait": portrait}\n \n @property\n def member_info(self):\n current_member = self.portal_state.member()\n if not current_member or not current_member.getId():\n- return {\'url\': None, \'email\': None}\n+ return {"url": None, "email": None}\n \n return {\n- \'url\': quote_plus(current_member.getId()),\n- \'email\': current_member.getProperty(\'email\')\n+ "url": quote_plus(current_member.getId()),\n+ "email": current_member.getProperty("email"),\n }\n \n @property\n def author_content(self):\n results = []\n \n- plone_view = self.context.restrictedTraverse(\n- \'@@plone\'\n- )\n+ plone_view = self.context.restrictedTraverse("@@plone")\n \n brains = self.portal_catalog.searchResults(\n- Creator=self.username,\n- sort_on=\'created\',\n- sort_order=\'reverse\'\n+ Creator=self.username, sort_on="created", sort_order="reverse"\n )\n \n for brain in brains[:10]:\n- results.append({\n- \'title\': pretty_title_or_id(\n- self, brain\n- ),\n- \'date\': plone_view.toLocalizedTime(\n- brain.Date\n- ),\n- \'url\': brain.getURL()\n- })\n+ results.append(\n+ {\n+ "title": pretty_title_or_id(self, brain),\n+ "date": plone_view.toLocalizedTime(brain.Date),\n+ "url": brain.getURL(),\n+ }\n+ )\n \n return results\n \n@@ -213,43 +197,31 @@ def home_folder(self, username):\n return self.membership_tool.getHomeFolder(id=username)\n \n def __call__(self):\n+ self.portal_properties = getUtility(IPropertiesTool)\n \n- self.portal_properties = getUtility(\n- IPropertiesTool\n- )\n-\n- self.portal_catalog = getToolByName(\n- self.context, \'portal_catalog\'\n- )\n+ self.portal_catalog = getToolByName(self.context, "portal_catalog")\n \n # XXX: getUtility call does not work.\n- self.membership_tool = getToolByName(\n- self.context, \'portal_membership\'\n- )\n+ self.membership_tool = getToolByName(self.context, "portal_membership")\n \n self.portal_state = getMultiAdapter(\n- (self.context, self.request),\n- name=\'plone_portal_state\'\n+ (self.context, self.request), name="plone_portal_state"\n )\n \n- self.feedback_form = AuthorFeedbackForm(\n- self.context, self.request\n- )\n+ self.feedback_form = AuthorFeedbackForm(self.context, self.request)\n self.feedback_form.update()\n self.feedback_form.widgets["author"].mode = HIDDEN_MODE\n self.feedback_form.widgets["referer"].mode = HIDDEN_MODE\n self.feedback_form.widgets["author"].value = self.username\n self.feedback_form.widgets["referer"].value = self.request.get(\n- \'referer\',\n- self.request.get(\'HTTP_REFERER\', \'unknown url\')\n+ "referer", self.request.get("HTTP_REFERER", "unknown url")\n )\n \n registry = getUtility(IRegistry)\n- security_settings = registry.forInterface(\n- ISecuritySchema, prefix=\'plone\')\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n allow_anonymous_view_about = security_settings.allow_anon_views_about\n \n- mail_settings = registry.forInterface(IMailSchema, prefix=\'plone\')\n+ mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n self.email_from_address = mail_settings.email_from_address\n \n if self.is_anonymous and not allow_anonymous_view_about:\ndiff --git a/Products/CMFPlone/browser/contact_info.py b/Products/CMFPlone/browser/contact_info.py\nindex dd38f91da0..3e9e5ac6aa 100644\n--- a/Products/CMFPlone/browser/contact_info.py\n+++ b/Products/CMFPlone/browser/contact_info.py\n@@ -29,9 +29,8 @@\n \n \n class ContactForm(AutoExtensibleForm, form.Form):\n-\n- template = ViewPageTemplateFile(\'templates/contact-info.pt\')\n- template_mailview = \'@@contact-info-email\'\n+ template = ViewPageTemplateFile("templates/contact-info.pt")\n+ template_mailview = "@@contact-info-email"\n \n schema = IContactForm\n ignoreContext = True\n@@ -44,14 +43,11 @@ def mailhost_is_configured(self):\n return False\n return True\n \n- @button.buttonAndHandler(_(\'label_send\', default=\'Send\'), name=\'send\')\n+ @button.buttonAndHandler(_("label_send", default="Send"), name="send")\n def handle_send(self, action):\n data, errors = self.extractData()\n if errors:\n- IStatusMessage(self.request).add(\n- self.formErrorsMessage,\n- type=\'error\'\n- )\n+ IStatusMessage(self.request).add(self.formErrorsMessage, type="error")\n \n return\n \n@@ -74,25 +70,25 @@ def generate_mail(self, variables, encoding=None):\n return result\n \n def send_message(self, data):\n- subject = data.get(\'subject\')\n+ subject = data.get("subject")\n \n portal = getSite()\n registry = getUtility(IRegistry)\n- mail_settings = registry.forInterface(IMailSchema, prefix=\'plone\')\n+ mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n send_to_address = mail_settings.email_from_address\n from_address = mail_settings.email_from_address\n registry = getUtility(IRegistry)\n- encoding = registry.get(\'plone.email_charset\', \'utf-8\')\n- host = getToolByName(self.context, \'MailHost\')\n+ encoding = registry.get("plone.email_charset", "utf-8")\n+ host = getToolByName(self.context, "MailHost")\n \n- data[\'url\'] = portal.absolute_url()\n+ data["url"] = portal.absolute_url()\n message = self.generate_mail(data)\n if isinstance(message, bytes):\n # Maybe someone has customized \'generate_mail\'\n # and still handles the encoding keyword argument.\n message = message.decode(encoding)\n message = message_from_string(message)\n- message[\'Reply-To\'] = data[\'sender_from_address\']\n+ message["Reply-To"] = data["sender_from_address"]\n \n try:\n # This actually sends out the mail\n@@ -101,18 +97,21 @@ def send_message(self, data):\n send_to_address,\n from_address,\n subject=subject,\n- charset=encoding\n+ charset=encoding,\n )\n except (SMTPException, RuntimeError) as e:\n log.error(e)\n- plone_utils = getToolByName(portal, \'plone_utils\')\n+ plone_utils = getToolByName(portal, "plone_utils")\n exception = plone_utils.exceptionString()\n- message = _(\'Unable to send mail: ${exception}\',\n- mapping={\'exception\': exception})\n- IStatusMessage(self.request).add(message, type=\'error\')\n+ message = _(\n+ "Unable to send mail: ${exception}", mapping={"exception": exception}\n+ )\n+ IStatusMessage(self.request).add(message, type="error")\n \n def send_feedback(self):\n IStatusMessage(self.request).add(\n- _(\'A mail has now been sent to the site administrator \'\n- \'regarding your questions and/or comments.\')\n+ _(\n+ "A mail has now been sent to the site administrator "\n+ "regarding your questions and/or comments."\n+ )\n )\ndiff --git a/Products/CMFPlone/browser/defaultpage.py b/Products/CMFPlone/browser/defaultpage.py\nindex 026b54e94b..84b4fc0db0 100644\n--- a/Products/CMFPlone/browser/defaultpage.py\n+++ b/Products/CMFPlone/browser/defaultpage.py\n@@ -8,7 +8,6 @@\n \n @implementer(IDefaultPage)\n class DefaultPage(BrowserView):\n-\n def isDefaultPage(self, obj):\n return is_default_page(aq_inner(self.context), obj)\n \ndiff --git a/Products/CMFPlone/browser/exceptions.py b/Products/CMFPlone/browser/exceptions.py\nindex 7c3825c53e..65853e6f10 100644\n--- a/Products/CMFPlone/browser/exceptions.py\n+++ b/Products/CMFPlone/browser/exceptions.py\n@@ -10,11 +10,10 @@\n \n \n class ExceptionView(BrowserView):\n- basic_template = ViewPageTemplateFile(\'templates/basic_error_message.pt\')\n+ basic_template = ViewPageTemplateFile("templates/basic_error_message.pt")\n \n def is_manager(self):\n- return getSecurityManager().checkPermission(\n- \'Manage portal\', self.context)\n+ return getSecurityManager().checkPermission("Manage portal", self.context)\n \n @property\n @memoize\n@@ -35,27 +34,24 @@ def __call__(self):\n request = self.request\n \n exc_type, value, traceback = sys.exc_info()\n- error_tb = \'\'.join(\n- format_exception(exc_type, value, traceback, as_html=False))\n+ error_tb = "".join(format_exception(exc_type, value, traceback, as_html=False))\n request.response.setStatus(exc_type)\n \n # Indicate exception as JSON\n- if "text/html" not in request.getHeader(\'Accept\', \'\'):\n+ if "text/html" not in request.getHeader("Accept", ""):\n request.response.setHeader("Content-Type", "application/json")\n- return json.dumps({\n- \'error_type\': error_type,\n- })\n+ return json.dumps(\n+ {\n+ "error_type": error_type,\n+ }\n+ )\n \n # Render page with user-facing error notice\n- request.set(\'disable_border\', True)\n- request.set(\'disable_plone.leftcolumn\', True)\n- request.set(\'disable_plone.rightcolumn\', True)\n+ request.set("disable_border", True)\n+ request.set("disable_plone.leftcolumn", True)\n+ request.set("disable_plone.rightcolumn", True)\n \n try:\n- return self.index(\n- error_type=error_type,\n- error_tb=error_tb)\n+ return self.index(error_type=error_type, error_tb=error_tb)\n except:\n- return self.basic_template(\n- error_type=error_type,\n- error_tb=error_tb)\n+ return self.basic_template(error_type=error_type, error_tb=error_tb)\ndiff --git a/Products/CMFPlone/browser/global_statusmessage.py b/Products/CMFPlone/browser/global_statusmessage.py\nindex b0971d10f6..55aad6dd60 100644\n--- a/Products/CMFPlone/browser/global_statusmessage.py\n+++ b/Products/CMFPlone/browser/global_statusmessage.py\n@@ -8,7 +8,7 @@\n class GlobalStatusMessage(BrowserView):\n """Display messages to the current user"""\n \n- index = ViewPageTemplateFile(\'templates/global_statusmessage.pt\')\n+ index = ViewPageTemplateFile("templates/global_statusmessage.pt")\n \n def __call__(self):\n return self.index()\ndiff --git a/Products/CMFPlone/browser/icons.py b/Products/CMFPlone/browser/icons.py\nindex 6858edb649..c3c52ee955 100644\n--- a/Products/CMFPlone/browser/icons.py\n+++ b/Products/CMFPlone/browser/icons.py\n@@ -21,46 +21,50 @@\n \n SVG_MODIFER = {}\n \n+\n def _add_aria_title(svgtree, cfg):\n if not cfg.get("title"):\n return\n root = svgtree.getroot()\n ns = root.nsmap.get(None, "")\n # set title tag\n- title = root.find(f\'{{{ns}}}title\')\n+ title = root.find(f"{{{ns}}}title")\n if title is None:\n title = etree.Element("title")\n root.append(title)\n- title.text = cfg[\'title\']\n+ title.text = cfg["title"]\n # add aria attr\n root.attrib["aria-labelledby"] = "title"\n \n \n-SVG_MODIFER[\'add_aria_title\'] = _add_aria_title\n+SVG_MODIFER["add_aria_title"] = _add_aria_title\n \n ADDITIONAL_CLASSES = [\n # this classes are added to all svg root elements\n "plone-icon",\n ]\n \n+\n def _add_css_class(svgtree, cfg):\n- cssclass = cfg.get(\'cssclass\', "")\n+ cssclass = cfg.get("cssclass", "")\n root = svgtree.getroot()\n- current = root.attrib.get(\'class\', \'\')\n- root.attrib[\'class\'] = f"{\' \'.join(ADDITIONAL_CLASSES)} {cfg[\'cssclass\']} {current}"\n+ current = root.attrib.get("class", "")\n+ root.attrib["class"] = f"{\' \'.join(ADDITIONAL_CLASSES)} {cfg[\'cssclass\']} {current}"\n+\n+\n+SVG_MODIFER["add_css_class"] = _add_css_class\n \n-SVG_MODIFER[\'add_css_class\'] = _add_css_class\n \n def _strip_id(svgtree, cfg):\n for el in svgtree.getroot().xpath("//*[@id]"):\n del el.attrib["id"]\n \n-SVG_MODIFER[\'strip_id\'] = _strip_id\n+\n+SVG_MODIFER["strip_id"] = _strip_id\n \n \n @implementer(IPublishTraverse)\n class IconsView(BrowserView):\n-\n prefix = "plone.icon."\n defaulticon = "++plone++icons/plone.svg"\n name = ""\n@@ -125,11 +129,13 @@ def tag(self, name, tag_class="", tag_alt=""):\n logger.exception(f"SVG File: {iconfile.path}")\n with open(iconfile.path, "rb") as fh:\n return fh.read()\n- if svgtree.docinfo.root_name.lower() != \'svg\':\n- raise ValueError(f"SVG file content root tag mismatch (not svg but {svgtree.docinfo.root_name}): {iconfile.path}")\n+ if svgtree.docinfo.root_name.lower() != "svg":\n+ raise ValueError(\n+ f"SVG file content root tag mismatch (not svg but {svgtree.docinfo.root_name}): {iconfile.path}"\n+ )\n modifier_cfg = {\n- \'cssclass\': tag_class,\n- \'title\': tag_alt,\n+ "cssclass": tag_class,\n+ "title": tag_alt,\n }\n for name, modifier in SVG_MODIFER.items():\n __traceback_info__ = name\ndiff --git a/Products/CMFPlone/browser/interfaces.py b/Products/CMFPlone/browser/interfaces.py\nindex 2e08f93b5e..32c764d342 100644\n--- a/Products/CMFPlone/browser/interfaces.py\n+++ b/Products/CMFPlone/browser/interfaces.py\n@@ -12,40 +12,31 @@\n zope.deferredimport.deprecated(\n "It has been moved to plone.app.layout.navigation.interfaces. "\n "This alias will be removed in Plone 5.0",\n- INavigationRoot=\'plone.app.layout.navigation.interfaces:INavigationRoot\',\n+ INavigationRoot="plone.app.layout.navigation.interfaces:INavigationRoot",\n )\n \n \n class INavigationBreadcrumbs(Interface):\n-\n def breadcrumbs():\n- """Breadcrumbs for Navigation.\n- """\n+ """Breadcrumbs for Navigation."""\n \n \n class INavigationTabs(Interface):\n-\n- def topLevelTabs(actions=None, category=\'portal_tabs\'):\n- """Top level tabs\n- """\n+ def topLevelTabs(actions=None, category="portal_tabs"):\n+ """Top level tabs"""\n \n \n class INavigationTree(Interface):\n-\n def navigationTreeRootPath():\n- """Get the path to the root of the navigation tree\n- """\n+ """Get the path to the root of the navigation tree"""\n \n def navigationTree():\n- """Navigation tree\n- """\n+ """Navigation tree"""\n \n \n class ISiteMap(Interface):\n-\n def siteMap():\n- """Site map\n- """\n+ """Site map"""\n \n \n class INavigationPortlet(Interface):\n@@ -78,12 +69,12 @@ class INewsPortlet(Interface):\n \n def published_news_items():\n """Returns 5 most recently published News Items in reverse\n- chronological order\n+ chronological order\n """\n \n def all_news_link():\n """Returns URL, relative to the portal, of a page that display all\n- published News Items\n+ published News Items\n """\n \n \n@@ -92,17 +83,17 @@ class IEventsPortlet(Interface):\n \n def published_events():\n """Returns 5 most recently published News Items in reverse\n- chronological order\n+ chronological order\n """\n \n def all_events_link():\n """Returns URL, relative to the portal, of a page that display all\n- published News Items\n+ published News Items\n """\n \n def prev_events_link():\n """Returns URL, relative to the portal, of a page that display all\n- past events.\n+ past events.\n """\n \n \n@@ -114,7 +105,6 @@ def results():\n \n \n class ICalendarPortlet(Interface):\n-\n def DateTime():\n """ """\n \n@@ -174,7 +164,7 @@ def getMonthName(self, month):\n \n def isToday(self, day):\n """Returns True if the given day and the current month and year equals\n- today, otherwise False.\n+ today, otherwise False.\n """\n \n \n@@ -200,29 +190,28 @@ class IPlone(Interface):\n """ """\n \n def getCurrentUrl():\n- """ Returns the actual url plus the query string. """\n+ """Returns the actual url plus the query string."""\n \n def uniqueItemIndex(pos=0):\n """Return an index iterator."""\n \n def toLocalizedTime(time, long_format=None, time_only=None):\n- """ The time parameter must be either a string that is suitable for\n- initializing a DateTime or a DateTime object. Returns a localized\n- string.\n+ """The time parameter must be either a string that is suitable for\n+ initializing a DateTime or a DateTime object. Returns a localized\n+ string.\n """\n \n def toLocalizedSize(size):\n- """ Convert an integer to a localized size string\n+ """Convert an integer to a localized size string\n 3322 -> 3KB in english, 3Ko in french\n """\n \n def normalizeString(text):\n- """Normalizes a title to an id.\n- """\n+ """Normalizes a title to an id."""\n \n def isDefaultPageInFolder():\n- """ Returns a boolean indicating whether the current context is the\n- default page of its parent folder.\n+ """Returns a boolean indicating whether the current context is the\n+ default page of its parent folder.\n """\n \n def isStructuralFolder():\n@@ -234,139 +223,124 @@ def isStructuralFolder():\n """\n \n def navigationRootPath():\n- """Get the current navigation root path\n- """\n+ """Get the current navigation root path"""\n \n def navigationRootUrl():\n- """Get the url to the current navigation root\n- """\n+ """Get the url to the current navigation root"""\n \n def getParentObject():\n """Returns the parent of the current object, equivalent to\n- aq_inner(aq_parent(context)), or context.aq_inner.getParentNode()\n+ aq_inner(aq_parent(context)), or context.aq_inner.getParentNode()\n """\n \n def getCurrentFolder():\n """If the context is the default page of a folder or is not itself a\n- folder, the parent is returned, otherwise the object itself is\n- returned. This is useful for providing a context for methods\n- which wish to act on what is considered the current folder in the\n- ui.\n+ folder, the parent is returned, otherwise the object itself is\n+ returned. This is useful for providing a context for methods\n+ which wish to act on what is considered the current folder in the\n+ ui.\n """\n \n def getCurrentFolderUrl():\n """Returns the URL of the current folder as determined by\n- self.getCurrentFolder(), used heavily in actions.\n+ self.getCurrentFolder(), used heavily in actions.\n """\n \n def getCurrentObjectUrl():\n """Returns the URL of the current object unless that object is a\n- folder default page, in which case it returns the parent.\n+ folder default page, in which case it returns the parent.\n """\n \n def isFolderOrFolderDefaultPage():\n """Returns true only if the current object is either a folder (as\n- determined by isStructuralFolder) or the default page in context.\n+ determined by isStructuralFolder) or the default page in context.\n """\n \n def isPortalOrPortalDefaultPage():\n """Returns true only if the current object is either the portal object\n- or the default page of the portal.\n+ or the default page of the portal.\n """\n \n def getViewTemplateId():\n """Returns the template Id corresponding to the default view method of\n- the context object.\n+ the context object.\n """\n \n def showToolbar():\n- """Returns true if the editable border should be shown\n- """\n+ """Returns true if the editable border should be shown"""\n \n def cropText(text, length, ellipsis):\n- """ Crop text on a word boundary """\n+ """Crop text on a word boundary"""\n \n def site_encoding():\n- """ returns site encoding """\n+ """returns site encoding"""\n \n def patterns_settings():\n- """ returns mockup pattern settings """\n+ """returns mockup pattern settings"""\n \n \n class ISendToForm(Interface):\n- """ Interface for describing the \'sendto\' form """\n+ """Interface for describing the \'sendto\' form"""\n \n send_to_address = Email(\n- title=_(\'label_send_to_mail\',\n- default=\'Send to\'),\n- description=_(\'help_send_to_mail\',\n- default=\'The e-mail address to send this link to.\'),\n- required=True\n+ title=_("label_send_to_mail", default="Send to"),\n+ description=_(\n+ "help_send_to_mail", default="The e-mail address to send this link to."\n+ ),\n+ required=True,\n )\n \n send_from_address = Email(\n- title=_(\'label_send_from\',\n- default=\'From\'),\n- description=_(\'help_send_from\',\n- default=\'Your email address.\'),\n- required=True\n+ title=_("label_send_from", default="From"),\n+ description=_("help_send_from", default="Your email address."),\n+ required=True,\n )\n \n comment = schema.Text(\n- title=_(\'label_comment\',\n- default=\'Comment\'),\n- description=_(\'help_comment_to_link\',\n- default=\'A comment about this link.\'),\n- required=False\n+ title=_("label_comment", default="Comment"),\n+ description=_("help_comment_to_link", default="A comment about this link."),\n+ required=False,\n )\n \n \n class IContactForm(Interface):\n- """ Interface for describing the contact info form """\n+ """Interface for describing the contact info form"""\n \n sender_fullname = schema.TextLine(\n- title=_(\'label_sender_fullname\',\n- default=\'Name\'),\n- description=_(\'help_sender_fullname\',\n- default=\'Please enter your full name.\'),\n- required=True\n+ title=_("label_sender_fullname", default="Name"),\n+ description=_("help_sender_fullname", default="Please enter your full name."),\n+ required=True,\n )\n \n sender_from_address = Email(\n- title=_(\'label_sender_from_address\',\n- default=\'From\'),\n- description=_(\'help_sender_from_address\',\n- default=\'Please enter your e-mail address.\'),\n- required=True\n+ title=_("label_sender_from_address", default="From"),\n+ description=_(\n+ "help_sender_from_address", default="Please enter your e-mail address."\n+ ),\n+ required=True,\n )\n \n subject = schema.TextLine(\n- title=_(\'label_subject\',\n- default=\'Subject\'),\n- required=True\n+ title=_("label_subject", default="Subject"), required=True\n )\n \n message = schema.Text(\n- title=_(\'label_message\',\n- default=\'Message\'),\n- description=_(\'help_message\',\n- default=\'Please enter the message you want to send.\'),\n- required=False\n+ title=_("label_message", default="Message"),\n+ description=_(\n+ "help_message", default="Please enter the message you want to send."\n+ ),\n+ required=False,\n )\n \n \n class IAuthorFeedbackForm(Interface):\n- """ Interface describing the author feedback form """\n+ """Interface describing the author feedback form"""\n \n subject = schema.TextLine(\n- title=_(\'label_subject\', default=\'Subject\'),\n- required=True\n+ title=_("label_subject", default="Subject"), required=True\n )\n \n- message = schema.Text(\n- title=_(\'label_message\', default=\'Message\'),\n- required=True\n- )\n+ message = schema.Text(title=_("label_message", default="Message"), required=True)\n \n author = schema.TextLine()\n referer = schema.TextLine(required=False)\ndiff --git a/Products/CMFPlone/browser/login/login.py b/Products/CMFPlone/browser/login/login.py\nindex 12f920cd65..a7fdd67897 100644\n--- a/Products/CMFPlone/browser/login/login.py\n+++ b/Products/CMFPlone/browser/login/login.py\n@@ -28,58 +28,58 @@\n # TODO: Scale down this list now that we\'ve removed a lot of\n # templates.\n LOGIN_TEMPLATE_IDS = [\n- \'localhost\',\n- \'logged-out\',\n- \'logged_in\',\n- \'login\',\n- \'login_failed\',\n- \'login_form\',\n- \'login_password\',\n- \'login_success\',\n- \'logout\',\n- \'mail_password\',\n- \'mail_password_form\',\n- \'member_search_results\',\n- \'pwreset_finish\',\n- \'passwordreset\',\n- \'register\',\n- \'registered\',\n- \'require_login\',\n+ "localhost",\n+ "logged-out",\n+ "logged_in",\n+ "login",\n+ "login_failed",\n+ "login_form",\n+ "login_password",\n+ "login_success",\n+ "logout",\n+ "mail_password",\n+ "mail_password_form",\n+ "member_search_results",\n+ "pwreset_finish",\n+ "passwordreset",\n+ "register",\n+ "registered",\n+ "require_login",\n ]\n \n \n @implementer(ILoginForm)\n class LoginForm(form.EditForm):\n- """ Implementation of the login form """\n+ """Implementation of the login form"""\n \n fields = field.Fields(ILoginFormSchema)\n \n- id = \'LoginForm\'\n- label = _(\'label_log_in\', default=\'Log in\')\n+ id = "LoginForm"\n+ label = _("label_log_in", default="Log in")\n \n ignoreContext = True\n- prefix = \'\'\n+ prefix = ""\n \n def render(self):\n registry = queryUtility(IRegistry)\n- ext_login_url = registry[\'plone.external_login_url\']\n+ ext_login_url = registry["plone.external_login_url"]\n if ext_login_url:\n return self._handle_external_login(ext_login_url)\n return self.index()\n \n def _handle_external_login(self, url):\n """Handle login on this portal where login is external."""\n- next_ = self.request.get(\'next\', None)\n- came_from = self.request.get(\'came_from\')\n+ next_ = self.request.get("next", None)\n+ came_from = self.request.get("came_from")\n urlparts = [part for part in parse.urlparse(url)]\n qs = dict(parse.parse_qsl(urlparts[4]))\n- portal_url = getToolByName(self.context, \'portal_url\')\n+ portal_url = getToolByName(self.context, "portal_url")\n if next_ is not None and not portal_url.isURLInPortal(next_):\n next_ = None\n if next_ is not None:\n- qs[\'next\'] = next_\n+ qs["next"] = next_\n if came_from:\n- qs[\'came_from\'] = came_from\n+ qs["came_from"] = came_from\n urlparts[4] = parse.urlencode(qs)\n self.request.response.redirect(parse.urlunparse(urlparts))\n \n@@ -93,38 +93,37 @@ def _get_auth(self):\n pass\n \n def updateWidgets(self):\n- super().updateWidgets(prefix=\'\')\n+ super().updateWidgets(prefix="")\n \n auth = self._get_auth()\n \n if auth:\n- widgetname_login = auth.get(\'name_cookie\', \'__ac_name\')\n- widgetname_password = auth.get(\'pw_cookie\', \'__ac_password\')\n+ widgetname_login = auth.get("name_cookie", "__ac_name")\n+ widgetname_password = auth.get("pw_cookie", "__ac_password")\n else:\n- widgetname_login = \'__ac_name\'\n- widgetname_password = \'__ac_password\'\n+ widgetname_login = "__ac_name"\n+ widgetname_password = "__ac_password"\n \n- self.widgets[\'ac_name\'].name = widgetname_login\n- self.widgets[\'ac_name\'].id = widgetname_login\n- self.widgets[\'ac_password\'].name = widgetname_password\n- self.widgets[\'ac_password\'].id = widgetname_password\n+ self.widgets["ac_name"].name = widgetname_login\n+ self.widgets["ac_name"].id = widgetname_login\n+ self.widgets["ac_password"].name = widgetname_password\n+ self.widgets["ac_password"].id = widgetname_password\n \n if self.use_email_as_login():\n- self.widgets[\'ac_name\'].label = _(\'label_email\',\n- default=\'Email\')\n- self.widgets[\'came_from\'].mode = HIDDEN_MODE\n- self.widgets[\'came_from\'].value = self.get_came_from()\n+ self.widgets["ac_name"].label = _("label_email", default="Email")\n+ self.widgets["came_from"].mode = HIDDEN_MODE\n+ self.widgets["came_from"].value = self.get_came_from()\n \n def get_came_from(self):\n- came_from = self.request.get(\'came_from\', None)\n+ came_from = self.request.get("came_from", None)\n if not came_from:\n- came_from = self.request.get(\'HTTP_REFERER\', None)\n+ came_from = self.request.get("HTTP_REFERER", None)\n if not came_from:\n return\n- url_tool = getToolByName(self.context, \'portal_url\')\n+ url_tool = getToolByName(self.context, "portal_url")\n if not url_tool.isURLInPortal(came_from):\n return\n- came_from_path = parse.urlparse(came_from)[2].split(\'/\')\n+ came_from_path = parse.urlparse(came_from)[2].split("/")\n for login_template_id in LOGIN_TEMPLATE_IDS:\n if login_template_id in came_from_path:\n return\n@@ -132,13 +131,13 @@ def get_came_from(self):\n \n def updateActions(self):\n super().updateActions()\n- self.actions[\'login\'].addClass(\'btn-primary\')\n+ self.actions["login"].addClass("btn-primary")\n \n def _post_login(self):\n- membership_tool = getToolByName(self.context, \'portal_membership\')\n+ membership_tool = getToolByName(self.context, "portal_membership")\n member = membership_tool.getAuthenticatedMember()\n- must_change_password = member.getProperty(\'must_change_password\', 0)\n- login_time = member.getProperty(\'login_time\', None)\n+ must_change_password = member.getProperty("must_change_password", 0)\n+ login_time = member.getProperty("login_time", None)\n is_initial_login = not has_logged_in(login_time)\n \n membership_tool.loginUser(self.request)\n@@ -149,44 +148,44 @@ def _post_login(self):\n self.force_password_change()\n return is_initial_login\n \n- @button.buttonAndHandler(_(\'Log in\'), name=\'login\')\n+ @button.buttonAndHandler(_("Log in"), name="login")\n def handleLogin(self, action):\n data, errors = self.extractData()\n if errors:\n self.status = self.formErrorsMessage\n return\n- membership_tool = getToolByName(self.context, \'portal_membership\')\n+ membership_tool = getToolByName(self.context, "portal_membership")\n status_msg = IStatusMessage(self.request)\n if membership_tool.isAnonymousUser():\n- self.request.response.expireCookie(\'__ac\', path=\'/\')\n+ self.request.response.expireCookie("__ac", path="/")\n if self.use_email_as_login():\n status_msg.addStatusMessage(\n _(\n- \'Login failed. Both email address and password are \'\n- \'case sensitive, check that caps lock is not enabled.\'\n+ "Login failed. Both email address and password are "\n+ "case sensitive, check that caps lock is not enabled."\n ),\n- \'error\',\n+ "error",\n )\n else:\n status_msg.addStatusMessage(\n _(\n- \'Login failed. Both login name and password are case \'\n- \'sensitive, check that caps lock is not enabled.\'\n+ "Login failed. Both login name and password are case "\n+ "sensitive, check that caps lock is not enabled."\n ),\n- \'error\',\n+ "error",\n )\n return\n \n is_initial_login = self._post_login()\n status_msg.addStatusMessage(\n _(\n- \'you_are_now_logged_in\',\n- default=\'Welcome! You are now logged in.\',\n+ "you_are_now_logged_in",\n+ default="Welcome! You are now logged in.",\n ),\n- \'info\'\n+ "info",\n )\n \n- came_from = data.get(\'came_from\', None)\n+ came_from = data.get("came_from", None)\n self.redirect_after_login(came_from, is_initial_login)\n \n def handle_initial_login(self):\n@@ -206,10 +205,7 @@ def force_password_change(self):\n handler()\n \n def redirect_after_login(self, came_from=None, is_initial_login=False):\n- adapter = queryMultiAdapter(\n- (self.context, self.request),\n- IRedirectAfterLogin\n- )\n+ adapter = queryMultiAdapter((self.context, self.request), IRedirectAfterLogin)\n if adapter:\n came_from = adapter(came_from, is_initial_login)\n if not came_from:\n@@ -219,81 +215,69 @@ def redirect_after_login(self, came_from=None, is_initial_login=False):\n \n def self_registration_enabled(self):\n registry = queryUtility(IRegistry)\n- security_settings = registry.forInterface(\n- ISecuritySchema,\n- prefix=\'plone\'\n- )\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n return security_settings.enable_self_reg\n \n def use_email_as_login(self):\n registry = queryUtility(IRegistry)\n- security_settings = registry.forInterface(\n- ISecuritySchema,\n- prefix=\'plone\'\n- )\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n return security_settings.use_email_as_login\n \n \n class FailsafeLoginForm(LoginForm):\n-\n def render(self):\n return self.index()\n \n \n class RequireLoginView(BrowserView):\n-\n def __call__(self):\n portal_state = getMultiAdapter(\n (self.context, self.request),\n- name=\'plone_portal_state\',\n+ name="plone_portal_state",\n )\n portal = portal_state.portal()\n if portal_state.anonymous():\n- url = f\'{portal.absolute_url():s}/login\'\n- came_from = self.request.get(\'came_from\', None)\n+ url = f"{portal.absolute_url():s}/login"\n+ came_from = self.request.get("came_from", None)\n if came_from:\n- url += f\'?came_from={parse.quote(came_from):s}\'\n+ url += f"?came_from={parse.quote(came_from):s}"\n else:\n- url = f\'{portal.absolute_url():s}/insufficient-privileges\'\n+ url = f"{portal.absolute_url():s}/insufficient-privileges"\n \n self.request.response.redirect(url)\n \n \n class InsufficientPrivilegesView(BrowserView):\n-\n def request_url(self):\n- return self.request.get(\'came_from\')\n+ return self.request.get("came_from")\n \n \n class InitialLoginPasswordChange(PasswordPanel):\n-\n def render(self):\n return self.index()\n \n @button.buttonAndHandler(\n- _(\'label_change_password\', default=\'Change Password\'),\n- name=\'reset_passwd\',\n+ _("label_change_password", default="Change Password"),\n+ name="reset_passwd",\n )\n def action_reset_passwd(self, action):\n- super().action_reset_passwd(\n- self, action)\n+ super().action_reset_passwd(self, action)\n if not action.form.widgets.errors:\n self.request.response.redirect(self.context.portal_url())\n \n \n class ForcedPasswordChange(PasswordPanel):\n-\n def render(self):\n return self.index()\n \n @button.buttonAndHandler(\n- _(\'label_change_password\', default=\'Change Password\'),\n- name=\'reset_passwd\',\n+ _("label_change_password", default="Change Password"),\n+ name="reset_passwd",\n )\n def action_reset_passwd(self, action):\n super().action_reset_passwd(self, action)\n if not action.form.widgets.errors:\n- membership_tool = getToolByName(self.context, \'portal_membership\')\n+ membership_tool = getToolByName(self.context, "portal_membership")\n member = membership_tool.getAuthenticatedMember()\n member.setProperties(must_change_password=0)\n self.request.response.redirect(self.context.portal_url())\ndiff --git a/Products/CMFPlone/browser/login/login_help.py b/Products/CMFPlone/browser/login/login_help.py\nindex 06f4170872..ae4bcc15b8 100644\n--- a/Products/CMFPlone/browser/login/login_help.py\n+++ b/Products/CMFPlone/browser/login/login_help.py\n@@ -31,7 +31,9 @@\n from email import message_from_string\n \n \n-SEND_USERNAME_TEMPLATE = _("mailtemplate_username_info", default="""From: {encoded_mail_sender}\n+SEND_USERNAME_TEMPLATE = _(\n+ "mailtemplate_username_info",\n+ default="""From: {encoded_mail_sender}\n To: {email}\n Subject: Your username for {portal_url}\n Content-Type: text/plain\n@@ -47,35 +49,31 @@\n \n --\n \n-{email_from_name}""")\n+{email_from_name}""",\n+)\n \n log = logging.getLogger(__name__)\n \n \n class RequestResetPassword(form.Form):\n-\n- id = \'RequestResetPassword\'\n- label = \'\'\n- fields = field.Fields(ILoginHelpFormSchema).select(\'reset_password\')\n+ id = "RequestResetPassword"\n+ label = ""\n+ fields = field.Fields(ILoginHelpFormSchema).select("reset_password")\n ignoreContext = True\n \n- render = ViewPageTemplateFile(\'templates/subform_render.pt\')\n+ render = ViewPageTemplateFile("templates/subform_render.pt")\n \n def updateActions(self):\n super().updateActions()\n- self.actions[\'reset\'].addClass(\'btn-primary\')\n+ self.actions["reset"].addClass("btn-primary")\n \n def updateWidgets(self):\n super().updateWidgets()\n if self.use_email_as_login():\n- self.widgets[\'reset_password\'].label = _(\n- \'label_email\',\n- default=\'Email\'\n- )\n+ self.widgets["reset_password"].label = _("label_email", default="Email")\n \n @button.buttonAndHandler(\n- _(\'button_pwreset_reset_password\', default=\'Reset your password\'),\n- name=\'reset\'\n+ _("button_pwreset_reset_password", default="Reset your password"), name="reset"\n )\n def handleResetPassword(self, action):\n data, errors = self.extractData()\n@@ -83,44 +81,51 @@ def handleResetPassword(self, action):\n self.status = self.formErrorsMessage\n return\n portal = getSite()\n- regtool = getToolByName(portal, \'portal_registration\')\n+ regtool = getToolByName(portal, "portal_registration")\n try:\n- regtool.mailPassword(data[\'reset_password\'], self.request)\n+ regtool.mailPassword(data["reset_password"], self.request)\n except ValueError as e:\n # Paranoia Warning!\n # We act as if a message has been sent to prevent probing Plone\n # for valid loginnames. Instead we log the error-message.\n- log.info(\'Error while trying to send a reset-password notice to user {}: {}\'.format(data[\'reset_password\'], e)) # noqa: E501\n+ log.info(\n+ "Error while trying to send a reset-password notice to user {}: {}".format(\n+ data["reset_password"], e\n+ )\n+ ) # noqa: E501\n pass\n \n IStatusMessage(self.request).addStatusMessage(\n- _(\'statusmessage_pwreset_password_mail_sent\', default=\'An \'\n- \'email has been sent with instructions on how to reset your \'\n- \'password.\'), \'info\')\n+ _(\n+ "statusmessage_pwreset_password_mail_sent",\n+ default="An "\n+ "email has been sent with instructions on how to reset your "\n+ "password.",\n+ ),\n+ "info",\n+ )\n \n def use_email_as_login(self):\n registry = getUtility(IRegistry)\n- security_settings = registry.forInterface(\n- ISecuritySchema, prefix=\'plone\')\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n return security_settings.use_email_as_login\n \n \n class RequestUsername(form.Form):\n-\n- id = \'RequestUsername\'\n- label = \'\'\n- fields = field.Fields(ILoginHelpFormSchema).select(\'recover_username\')\n+ id = "RequestUsername"\n+ label = ""\n+ fields = field.Fields(ILoginHelpFormSchema).select("recover_username")\n ignoreContext = True\n \n- render = ViewPageTemplateFile(\'templates/subform_render.pt\')\n+ render = ViewPageTemplateFile("templates/subform_render.pt")\n \n def updateActions(self):\n super().updateActions()\n- self.actions[\'get_username\'].addClass(\'btn-primary\')\n+ self.actions["get_username"].addClass("btn-primary")\n \n @button.buttonAndHandler(\n- _(\'button_pwreset_get_username\', default=\'Get your username\'),\n- name=\'get_username\'\n+ _("button_pwreset_get_username", default="Get your username"),\n+ name="get_username",\n )\n def handleGetUsername(self, action):\n data, errors = self.extractData()\n@@ -128,15 +133,15 @@ def handleGetUsername(self, action):\n self.status = self.formErrorsMessage\n return\n portal = getSite()\n- pas = getToolByName(portal, \'acl_users\')\n- email = data[\'recover_username\']\n+ pas = getToolByName(portal, "acl_users")\n+ email = data["recover_username"]\n results = pas.searchUsers(email=email, exact_match=True)\n send_email = True\n if not results:\n- log.info(f\'No user found for {email}\')\n+ log.info(f"No user found for {email}")\n send_email = False\n if len(results) > 1:\n- log.info(f\'More than one user found for {email}\')\n+ log.info(f"More than one user found for {email}")\n send_email = False\n if send_email:\n self.send_username(portal, results[0])\n@@ -147,51 +152,58 @@ def handleGetUsername(self, action):\n # Because of this we always act as if that an email has been sent.\n # Instead we log the error-message.\n IStatusMessage(self.request).addStatusMessage(\n- _(\'statusmessage_pwreset_username_mail_sent\',\n- default=\'An email has been sent with your username.\'),\n- \'info\'\n+ _(\n+ "statusmessage_pwreset_username_mail_sent",\n+ default="An email has been sent with your username.",\n+ ),\n+ "info",\n )\n \n def send_username(self, portal, userinfo):\n registry = getUtility(IRegistry)\n- encoding = registry.get(\'plone.email_charset\', \'utf-8\')\n+ encoding = registry.get("plone.email_charset", "utf-8")\n translated_template = translate(\n SEND_USERNAME_TEMPLATE,\n context=self.request,\n )\n \n mail_text = translated_template.format(\n- email=userinfo[\'email\'],\n+ email=userinfo["email"],\n portal_url=portal.absolute_url(),\n- fullname=userinfo[\'title\'],\n- login=userinfo[\'login\'],\n- email_from_name=registry[\'plone.email_from_name\'],\n+ fullname=userinfo["title"],\n+ login=userinfo["login"],\n+ email_from_name=registry["plone.email_from_name"],\n encoded_mail_sender=self.encoded_mail_sender(),\n )\n message_obj = message_from_string(mail_text.strip())\n- subject = message_obj[\'Subject\']\n- m_to = message_obj[\'To\']\n- m_from = message_obj[\'From\']\n- msg_type = message_obj.get(\'Content-Type\', \'text/plain\')\n+ subject = message_obj["Subject"]\n+ m_to = message_obj["To"]\n+ m_from = message_obj["From"]\n+ msg_type = message_obj.get("Content-Type", "text/plain")\n \n- host = getToolByName(portal, \'MailHost\')\n+ host = getToolByName(portal, "MailHost")\n try:\n- host.send(mail_text, m_to, m_from, subject=subject,\n- charset=encoding, immediate=True,\n- msg_type=msg_type)\n+ host.send(\n+ mail_text,\n+ m_to,\n+ m_from,\n+ subject=subject,\n+ charset=encoding,\n+ immediate=True,\n+ msg_type=msg_type,\n+ )\n except SMTPRecipientsRefused:\n # Don\'t disclose email address on failure\n- raise SMTPRecipientsRefused(\n- _(\'Recipient address rejected by server.\'))\n+ raise SMTPRecipientsRefused(_("Recipient address rejected by server."))\n except SMTPException as e:\n- raise(e)\n+ raise (e)\n \n def encode_mail_header(self, text):\n- """ Encodes text into correctly encoded email header """\n- return Header(safe_text(text), \'utf-8\')\n+ """Encodes text into correctly encoded email header"""\n+ return Header(safe_text(text), "utf-8")\n \n def encoded_mail_sender(self):\n- """ returns encoded version of Portal name """\n+ """returns encoded version of Portal name """\n registry = getUtility(IRegistry)\n mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n from_ = mail_settings.email_from_name\n@@ -201,12 +213,12 @@ def encoded_mail_sender(self):\n \n @implementer(ILoginHelpForm)\n class LoginHelpForm(form.EditForm):\n- \'\'\' Implementation of the login help form \'\'\'\n+ """Implementation of the login help form"""\n \n subforms = []\n \n- id = \'LoginHelpForm\'\n- label = _(\'heading_login_form_help\', default=\'Need Help?\')\n+ id = "LoginHelpForm"\n+ label = _("heading_login_form_help", default="Need Help?")\n \n ignoreContext = True\n \n@@ -238,6 +250,5 @@ def update(self):\n \n def use_email_as_login(self):\n registry = getUtility(IRegistry)\n- security_settings = registry.forInterface(\n- ISecuritySchema, prefix=\'plone\')\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n return security_settings.use_email_as_login\ndiff --git a/Products/CMFPlone/browser/login/logout.py b/Products/CMFPlone/browser/login/logout.py\nindex 874dbfb161..50017cfd80 100644\n--- a/Products/CMFPlone/browser/login/logout.py\n+++ b/Products/CMFPlone/browser/login/logout.py\n@@ -15,21 +15,20 @@ class ILoggedOutView(Interface):\n \n \n class LogoutView(BrowserView):\n-\n def __call__(self):\n- mt = getToolByName(self.context, \'portal_membership\')\n+ mt = getToolByName(self.context, "portal_membership")\n mt.logoutUser(self.request)\n- transaction_note(\'Logged out\')\n+ transaction_note("Logged out")\n # Handle external logout requests from other portals\n- next_ = self.request.get(\'next\', None)\n- portal_url = getToolByName(self.context, \'portal_url\')\n+ next_ = self.request.get("next", None)\n+ portal_url = getToolByName(self.context, "portal_url")\n if next_ is not None and portal_url.isURLInPortal(next_):\n target_url = next_\n else:\n- target_url = self.request.URL1 + \'/logged-out\'\n+ target_url = self.request.URL1 + "/logged-out"\n \n registry = queryUtility(IRegistry)\n- external_logout_url = registry[\'plone.external_logout_url\']\n+ external_logout_url = registry["plone.external_logout_url"]\n if external_logout_url:\n target_url = external_logout_url\n self.request.response.redirect(target_url)\n@@ -37,24 +36,16 @@ def __call__(self):\n \n @implementer(ILoggedOutView)\n class LoggedOutView(BrowserView):\n-\n def __call__(self):\n portal_state = getMultiAdapter(\n (self.context, self.request),\n- name=\'plone_portal_state\',\n+ name="plone_portal_state",\n )\n if portal_state.anonymous():\n- IStatusMessage(\n- self.request\n- ).addStatusMessage(\n- _(\n- \'statusmessage_logged_out\',\n- default=\'You are now logged out.\'\n- ),\n- \'info\',\n- )\n- self.request.response.redirect(\n- portal_state.navigation_root_url()\n+ IStatusMessage(self.request).addStatusMessage(\n+ _("statusmessage_logged_out", default="You are now logged out."),\n+ "info",\n )\n+ self.request.response.redirect(portal_state.navigation_root_url())\n return\n return self.index()\ndiff --git a/Products/CMFPlone/browser/login/mail_password.py b/Products/CMFPlone/browser/login/mail_password.py\nindex ada0ac13e6..6db3b8b03f 100644\n--- a/Products/CMFPlone/browser/login/mail_password.py\n+++ b/Products/CMFPlone/browser/login/mail_password.py\n@@ -5,12 +5,11 @@\n \n \n class MailPasswordView(BrowserView):\n-\n def __call__(self):\n response = None\n try:\n response = self.context.portal_registration.mailPassword(\n- self.request.form.get(\'userid\', \'\'),\n+ self.request.form.get("userid", ""),\n self.request,\n )\n except ValueError as e:\n@@ -22,6 +21,6 @@ def __call__(self):\n raise e\n IStatusMessage(self.request).add(msg)\n self.request.response.redirect(\n- self.context.absolute_url() + \'/mail_password_form\'\n+ self.context.absolute_url() + "/mail_password_form"\n )\n return response\ndiff --git a/Products/CMFPlone/browser/login/password_reset.py b/Products/CMFPlone/browser/login/password_reset.py\nindex 6039d58ba7..df65e3d200 100644\n--- a/Products/CMFPlone/browser/login/password_reset.py\n+++ b/Products/CMFPlone/browser/login/password_reset.py\n@@ -30,20 +30,17 @@\n \n @implementer(IPasswordResetToolView)\n class PasswordResetToolView(BrowserView):\n-\n @view.memoize_contextless\n def portal_state(self):\n- """ return portal_state of plone.app.layout\n- """\n- return getMultiAdapter((self.context, self.request),\n- name="plone_portal_state")\n+ """return portal_state of plone.app.layout"""\n+ return getMultiAdapter((self.context, self.request), name="plone_portal_state")\n \n def encode_mail_header(self, text):\n- """ Encodes text into correctly encoded email header """\n- return Header(safe_text(text), \'utf-8\')\n+ """Encodes text into correctly encoded email header"""\n+ return Header(safe_text(text), "utf-8")\n \n def encoded_mail_sender(self):\n- """ returns encoded version of Portal name """\n+ """returns encoded version of Portal name """\n registry = getUtility(IRegistry)\n mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n from_ = mail_settings.email_from_name\n@@ -54,9 +51,9 @@ def registered_notify_subject(self):\n portal_name = self.portal_state().portal_title()\n return translate(\n _(\n- \'mailtemplate_user_account_info\',\n- default=\'User Account Information for ${portal_name}\',\n- mapping={\'portal_name\': safe_text(portal_name)},\n+ "mailtemplate_user_account_info",\n+ default="User Account Information for ${portal_name}",\n+ mapping={"portal_name": safe_text(portal_name)},\n ),\n context=self.request,\n )\n@@ -64,18 +61,19 @@ def registered_notify_subject(self):\n def mail_password_subject(self):\n return translate(\n _(\n- \'mailtemplate_subject_resetpasswordrequest\',\n- default=\'Password reset request\',\n+ "mailtemplate_subject_resetpasswordrequest",\n+ default="Password reset request",\n ),\n context=self.request,\n )\n \n def construct_url(self, randomstring):\n- return \'{}/passwordreset/{}\'.format(\n- self.portal_state().navigation_root_url(), randomstring)\n+ return "{}/passwordreset/{}".format(\n+ self.portal_state().navigation_root_url(), randomstring\n+ )\n \n def expiration_timeout(self):\n- pw_tool = getToolByName(self.context, \'portal_password_reset\')\n+ pw_tool = getToolByName(self.context, "portal_password_reset")\n timeout = int(pw_tool.getExpirationTimeout() or 0)\n return timeout * 24 # timeout is in days, but templates want in hours.\n \n@@ -84,21 +82,18 @@ def expiration_timeout(self):\n class PasswordResetView(BrowserView):\n """ """\n \n- invalid = ViewPageTemplateFile(\'templates/pwreset_invalid.pt\')\n- expired = ViewPageTemplateFile(\'templates/pwreset_expired.pt\')\n- finish = ViewPageTemplateFile(\'templates/pwreset_finish.pt\')\n- form = ViewPageTemplateFile(\'templates/pwreset_form.pt\')\n+ invalid = ViewPageTemplateFile("templates/pwreset_invalid.pt")\n+ expired = ViewPageTemplateFile("templates/pwreset_expired.pt")\n+ finish = ViewPageTemplateFile("templates/pwreset_finish.pt")\n+ form = ViewPageTemplateFile("templates/pwreset_form.pt")\n subpath = None\n \n def _auto_login(self, userid, password):\n context = self.context\n- aclu = getToolByName(context, \'acl_users\')\n+ aclu = getToolByName(context, "acl_users")\n for name, plugin in aclu.plugins.listPlugins(ICredentialsUpdatePlugin):\n plugin.updateCredentials(\n- self.request,\n- self.request.response,\n- userid,\n- password\n+ self.request, self.request.response, userid, password\n )\n \n is_initial_login = False\n@@ -110,10 +105,10 @@ def _auto_login(self, userid, password):\n self.request.response.redirect(self.context.absolute_url())\n IStatusMessage(self.request).addStatusMessage(\n _(\n- \'password_reset_failed\',\n- default=\'Password reset failed.\',\n+ "password_reset_failed",\n+ default="Password reset failed.",\n ),\n- \'info\',\n+ "info",\n )\n return\n \n@@ -124,11 +119,10 @@ def _auto_login(self, userid, password):\n is_initial_login = self._post_login()\n IStatusMessage(self.request).addStatusMessage(\n _(\n- \'password_reset_successful\',\n- default=\'Password reset successful, \'\n- \'you are logged in now!\',\n+ "password_reset_successful",\n+ default="Password reset successful, " "you are logged in now!",\n ),\n- \'info\',\n+ "info",\n )\n self.redirect_after_login(is_initial_login=is_initial_login)\n finally:\n@@ -137,9 +131,9 @@ def _auto_login(self, userid, password):\n return\n \n def _post_login(self):\n- membership_tool = getToolByName(self.context, \'portal_membership\')\n+ membership_tool = getToolByName(self.context, "portal_membership")\n member = membership_tool.getAuthenticatedMember()\n- login_time = member.getProperty(\'login_time\', None)\n+ login_time = member.getProperty("login_time", None)\n is_initial_login = not has_logged_in(login_time)\n membership_tool.loginUser(self.request)\n if is_initial_login:\n@@ -155,10 +149,7 @@ def redirect_after_login(self, came_from=None, is_initial_login=False):\n # Note: for password reset a came_from parameter seems illogical.\n # But let\'s allow it, to be the same as in login.py.\n # The default implementation does not pass it in though.\n- adapter = queryMultiAdapter(\n- (self.context, self.request),\n- IRedirectAfterLogin\n- )\n+ adapter = queryMultiAdapter((self.context, self.request), IRedirectAfterLogin)\n if adapter:\n came_from = adapter(came_from, is_initial_login)\n if not came_from:\n@@ -170,8 +161,8 @@ def _reset_password(self, pw_tool, randomstring):\n state = self.getErrors()\n if state:\n return self.form()\n- userid = self.request.form.get(\'userid\')\n- password = self.request.form.get(\'password\')\n+ userid = self.request.form.get("userid")\n+ password = self.request.form.get("password")\n try:\n pw_tool.resetPassword(userid, randomstring, password)\n except ExpiredRequestError:\n@@ -181,7 +172,7 @@ def _reset_password(self, pw_tool, randomstring):\n except RuntimeError:\n return self.invalid()\n registry = getUtility(IRegistry)\n- if registry.get(\'plone.autologin_after_password_reset\', False):\n+ if registry.get("plone.autologin_after_password_reset", False):\n return self._auto_login(userid, password)\n return self.finish()\n \n@@ -190,10 +181,10 @@ def __call__(self):\n # Try traverse subpath first:\n randomstring = self.subpath[0]\n else:\n- randomstring = self.request.get(\'key\', None)\n+ randomstring = self.request.get("key", None)\n \n- pw_tool = getToolByName(self.context, \'portal_password_reset\')\n- if self.request.method == \'POST\':\n+ pw_tool = getToolByName(self.context, "portal_password_reset")\n+ if self.request.method == "POST":\n return self._reset_password(pw_tool, randomstring)\n try:\n pw_tool.verifyKey(randomstring)\n@@ -210,42 +201,41 @@ def publishTraverse(self, request, name):\n return self\n \n def getErrors(self):\n- if self.request.method != \'POST\':\n+ if self.request.method != "POST":\n return\n- password = self.request.form.get(\'password\')\n- password2 = self.request.form.get(\'password2\')\n- userid = self.request.form.get(\'userid\')\n- reg_tool = getToolByName(self.context, \'portal_registration\')\n+ password = self.request.form.get("password")\n+ password2 = self.request.form.get("password2")\n+ userid = self.request.form.get("userid")\n+ reg_tool = getToolByName(self.context, "portal_registration")\n pw_fail = reg_tool.testPasswordValidity(password, password2)\n state = {}\n if pw_fail:\n- state[\'password\'] = pw_fail\n+ state["password"] = pw_fail\n \n # Determine if we\'re checking userids or not\n- pw_tool = getToolByName(self.context, \'portal_password_reset\')\n+ pw_tool = getToolByName(self.context, "portal_password_reset")\n if not pw_tool.checkUser():\n return state\n \n if not userid:\n- state[\'userid\'] = _(\n- \'This field is required, please provide some information.\',\n+ state["userid"] = _(\n+ "This field is required, please provide some information.",\n )\n if state:\n- state[\'status\'] = \'failure\'\n- state[\'portal_status_message\'] = _(\n- \'Please correct the indicated errors.\'\n- )\n+ state["status"] = "failure"\n+ state["portal_status_message"] = _("Please correct the indicated errors.")\n return state\n \n def login_url(self):\n- portal_state = getMultiAdapter((self.context, self.request),\n- name="plone_portal_state")\n- return \'{}/login?__ac_name={}\'.format(\n- portal_state.navigation_root_url(),\n- self.request.form.get(\'userid\', \'\'))\n+ portal_state = getMultiAdapter(\n+ (self.context, self.request), name="plone_portal_state"\n+ )\n+ return "{}/login?__ac_name={}".format(\n+ portal_state.navigation_root_url(), self.request.form.get("userid", "")\n+ )\n \n def expiration_timeout(self):\n- pw_tool = getToolByName(self.context, \'portal_password_reset\')\n+ pw_tool = getToolByName(self.context, "portal_password_reset")\n timeout = int(pw_tool.getExpirationTimeout() or 0)\n return timeout * 24 # timeout is in days, but templates want in hours.\n \n@@ -257,7 +247,7 @@ def timeout_days(self):\n return self.context.getExpirationTimeout()\n \n def user_check(self):\n- return self.context._user_check and \'checked\' or None\n+ return self.context._user_check and "checked" or None\n \n @property\n def stats(self):\n@@ -266,17 +256,22 @@ def stats(self):\n about the number of open and expired reset requests.\n """\n # count expired reset requests by creating a list of it\n- bad = len([1 for expiry in self.context._requests.values()\n- if self.context.expired(expiry)])\n+ bad = len(\n+ [\n+ 1\n+ for expiry in self.context._requests.values()\n+ if self.context.expired(expiry)\n+ ]\n+ )\n # open reset requests are all requests without the expired ones\n good = len(self.context._requests) - bad\n return {"open": good, "expired": bad}\n \n def __call__(self):\n- if self.request.method == \'POST\':\n- timeout_days = safeToInt(self.request.get(\'timeout_days\'), 7)\n+ if self.request.method == "POST":\n+ timeout_days = safeToInt(self.request.get("timeout_days"), 7)\n self.context.setExpirationTimeout(timeout_days)\n self.context._user_check = bool(\n- self.request.get(\'user_check\', False),\n+ self.request.get("user_check", False),\n )\n return self.index()\ndiff --git a/Products/CMFPlone/browser/login/utils.py b/Products/CMFPlone/browser/login/utils.py\nindex 3d347c8c9c..83a68a1e42 100644\n--- a/Products/CMFPlone/browser/login/utils.py\n+++ b/Products/CMFPlone/browser/login/utils.py\n@@ -20,9 +20,9 @@ def has_logged_in(login_time):\n login_time = DateTime(login_time)\n except DateTimeSyntaxError:\n # https://github.com/plone/Products.CMFPlone/issues/3656\n- logger.warning(\'%r is not a valid login_time.\', login_time)\n+ logger.warning("%r is not a valid login_time.", login_time)\n return False\n # We used to compare login_time with DateTime(\'2000/01/01\'),\n # but it may have a timezone: I have seen both UTC and GTM+1.\n # So compare only the date part.\n- return login_time.Date() != \'2000/01/01\'\n+ return login_time.Date() != "2000/01/01"\ndiff --git a/Products/CMFPlone/browser/main_template.py b/Products/CMFPlone/browser/main_template.py\nindex b68867268e..4f815dba33 100644\n--- a/Products/CMFPlone/browser/main_template.py\n+++ b/Products/CMFPlone/browser/main_template.py\n@@ -6,16 +6,15 @@\n \n @implementer(IMainTemplate)\n class MainTemplate(BrowserView):\n-\n- ajax_template_name = \'templates/ajax_main_template.pt\'\n- main_template_name = \'templates/main_template.pt\'\n+ ajax_template_name = "templates/ajax_main_template.pt"\n+ main_template_name = "templates/main_template.pt"\n \n def __call__(self):\n return ViewPageTemplateFile(self.template_name)\n \n @property\n def template_name(self):\n- if self.request.form.get(\'ajax_load\'):\n+ if self.request.form.get("ajax_load"):\n return self.ajax_template_name\n else:\n return self.main_template_name\ndiff --git a/Products/CMFPlone/browser/navtree.py b/Products/CMFPlone/browser/navtree.py\nindex bba401a21b..d83d8b6a5e 100644\n--- a/Products/CMFPlone/browser/navtree.py\n+++ b/Products/CMFPlone/browser/navtree.py\n@@ -24,22 +24,20 @@\n # subclasses to buildFolderTree().\n \n security = ModuleSecurityInfo()\n-security.declarePrivate(\'plone\')\n-security.declarePrivate(\'utils\')\n+security.declarePrivate("plone")\n+security.declarePrivate("utils")\n \n \n @implementer(INavigationQueryBuilder)\n class NavtreeQueryBuilder:\n- """Build a navtree query based on the settings in navtree_properties\n- """\n+ """Build a navtree query based on the settings in navtree_properties"""\n \n def __init__(self, context):\n registry = getUtility(IRegistry)\n- navigation_settings = registry.forInterface(INavigationSchema,\n- prefix="plone")\n+ navigation_settings = registry.forInterface(INavigationSchema, prefix="plone")\n \n # Acquire a custom nav query if available\n- customQuery = getattr(context, \'getCustomNavQuery\', None)\n+ customQuery = getattr(context, "getCustomNavQuery", None)\n if customQuery is not None and utils.safe_callable(customQuery):\n query = customQuery()\n else:\n@@ -48,37 +46,37 @@ def __init__(self, context):\n # Construct the path query\n \n rootPath = getNavigationRoot(context)\n- currentPath = \'/\'.join(context.getPhysicalPath())\n+ currentPath = "/".join(context.getPhysicalPath())\n \n # If we are above the navigation root, a navtree query would return\n # nothing (since we explicitly start from the root always). Hence,\n # use a regular depth-1 query in this case.\n \n if not currentPath.startswith(rootPath):\n- query[\'path\'] = {\'query\': rootPath, \'depth\': 1}\n+ query["path"] = {"query": rootPath, "depth": 1}\n else:\n- query[\'path\'] = {\'query\': currentPath, \'navtree\': 1}\n+ query["path"] = {"query": currentPath, "navtree": 1}\n \n- query[\'path\'][\'navtree_start\'] = 0\n+ query["path"]["navtree_start"] = 0\n \n # XXX: It\'d make sense to use \'depth\' for bottomLevel, but it doesn\'t\n # seem to work with EPI.\n \n # Only list the applicable types\n- query[\'portal_type\'] = utils.typesToList(context)\n+ query["portal_type"] = utils.typesToList(context)\n \n # Apply the desired sort\n sortAttribute = navigation_settings.sort_tabs_on\n if sortAttribute is not None:\n- query[\'sort_on\'] = sortAttribute\n+ query["sort_on"] = sortAttribute\n if navigation_settings.sort_tabs_reversed:\n- query[\'sort_order\'] = \'desc\'\n+ query["sort_order"] = "desc"\n else:\n- query[\'sort_order\'] = \'asc\'\n+ query["sort_order"] = "asc"\n \n # Filter on workflow states, if enabled\n if navigation_settings.filter_on_workflow:\n- query[\'review_state\'] = navigation_settings.workflow_states_to_show\n+ query["review_state"] = navigation_settings.workflow_states_to_show\n \n self.query = query\n \n@@ -87,16 +85,17 @@ def __call__(self):\n \n \n class SitemapQueryBuilder(NavtreeQueryBuilder):\n- """Build a folder tree query suitable for a sitemap\n- """\n+ """Build a folder tree query suitable for a sitemap"""\n \n def __init__(self, context):\n NavtreeQueryBuilder.__init__(self, context)\n- portal_url = getToolByName(context, \'portal_url\')\n+ portal_url = getToolByName(context, "portal_url")\n registry = getUtility(IRegistry)\n- sitemap_depth = registry.get(\'plone.sitemap_depth\', 3)\n- self.query[\'path\'] = {\'query\': portal_url.getPortalPath(),\n- \'depth\': sitemap_depth}\n+ sitemap_depth = registry.get("plone.sitemap_depth", 3)\n+ self.query["path"] = {\n+ "query": portal_url.getPortalPath(),\n+ "depth": sitemap_depth,\n+ }\n \n \n @implementer(INavtreeStrategy)\n@@ -108,25 +107,25 @@ class SitemapNavtreeStrategy(NavtreeStrategyBase):\n def __init__(self, context, view=None):\n self.context = context\n \n- portal_url = getToolByName(context, \'portal_url\')\n+ portal_url = getToolByName(context, "portal_url")\n self.portal = portal_url.getPortalObject()\n registry = getUtility(IRegistry)\n- self.parentTypesNQ = registry.get(\n- \'plone.parent_types_not_to_query\', [])\n+ self.parentTypesNQ = registry.get("plone.parent_types_not_to_query", [])\n self.viewActionTypes = registry.get(\n- \'plone.types_use_view_action_in_listings\', [])\n+ "plone.types_use_view_action_in_listings", []\n+ )\n \n self.showAllParents = True\n self.rootPath = getNavigationRoot(context)\n \n- membership = getToolByName(context, \'portal_membership\')\n+ membership = getToolByName(context, "portal_membership")\n self.memberId = membership.getAuthenticatedMember().getId()\n \n def nodeFilter(self, node):\n- return not getattr(node[\'item\'], \'exclude_from_nav\', False)\n+ return not getattr(node["item"], "exclude_from_nav", False)\n \n def subtreeFilter(self, node):\n- portalType = getattr(node[\'item\'], \'portal_type\', None)\n+ portalType = getattr(node["item"], "portal_type", None)\n return portalType is None or portalType not in self.parentTypesNQ\n \n def decoratorFactory(self, node):\n@@ -134,58 +133,57 @@ def decoratorFactory(self, node):\n request = context.REQUEST\n \n newNode = node.copy()\n- item = node[\'item\']\n+ item = node["item"]\n \n- portalType = getattr(item, \'portal_type\', None)\n+ portalType = getattr(item, "portal_type", None)\n itemUrl = item.getURL()\n if portalType is not None and portalType in self.viewActionTypes:\n- itemUrl += \'/view\'\n+ itemUrl += "/view"\n \n useRemoteUrl = False\n- getRemoteUrl = getattr(item, \'getRemoteUrl\', None)\n- isCreator = self.memberId == getattr(item, \'Creator\', None)\n+ getRemoteUrl = getattr(item, "getRemoteUrl", None)\n+ isCreator = self.memberId == getattr(item, "Creator", None)\n if getRemoteUrl and not isCreator:\n useRemoteUrl = True\n \n- isFolderish = getattr(item, \'is_folderish\', None)\n+ isFolderish = getattr(item, "is_folderish", None)\n showChildren = False\n- if isFolderish and \\\n- (portalType is None or portalType not in self.parentTypesNQ):\n+ if isFolderish and (portalType is None or portalType not in self.parentTypesNQ):\n showChildren = True\n \n- layout_view = getMultiAdapter((context, request), name=\'plone_layout\')\n-\n- newNode[\'Title\'] = utils.pretty_title_or_id(context, item)\n- newNode[\'id\'] = item.getId\n- newNode[\'UID\'] = item.UID\n- newNode[\'absolute_url\'] = itemUrl\n- newNode[\'getURL\'] = itemUrl\n- newNode[\'path\'] = item.getPath()\n- newNode[\'Creator\'] = getattr(item, \'Creator\', None)\n- newNode[\'creation_date\'] = getattr(item, \'CreationDate\', None)\n- newNode[\'portal_type\'] = portalType\n- newNode[\'review_state\'] = getattr(item, \'review_state\', None)\n- newNode[\'Description\'] = getattr(item, \'Description\', None)\n- newNode[\'show_children\'] = showChildren\n- newNode[\'no_display\'] = False # We sort this out with the nodeFilter\n+ layout_view = getMultiAdapter((context, request), name="plone_layout")\n+\n+ newNode["Title"] = utils.pretty_title_or_id(context, item)\n+ newNode["id"] = item.getId\n+ newNode["UID"] = item.UID\n+ newNode["absolute_url"] = itemUrl\n+ newNode["getURL"] = itemUrl\n+ newNode["path"] = item.getPath()\n+ newNode["Creator"] = getattr(item, "Creator", None)\n+ newNode["creation_date"] = getattr(item, "CreationDate", None)\n+ newNode["portal_type"] = portalType\n+ newNode["review_state"] = getattr(item, "review_state", None)\n+ newNode["Description"] = getattr(item, "Description", None)\n+ newNode["show_children"] = showChildren\n+ newNode["no_display"] = False # We sort this out with the nodeFilter\n # BBB getRemoteUrl and link_remote are deprecated, remove in Plone 4\n- newNode[\'getRemoteUrl\'] = getattr(item, \'getRemoteUrl\', None)\n- newNode[\'useRemoteUrl\'] = useRemoteUrl\n- newNode[\'link_remote\'] = (\n- newNode[\'getRemoteUrl\'] and newNode[\'Creator\'] != self.memberId\n+ newNode["getRemoteUrl"] = getattr(item, "getRemoteUrl", None)\n+ newNode["useRemoteUrl"] = useRemoteUrl\n+ newNode["link_remote"] = (\n+ newNode["getRemoteUrl"] and newNode["Creator"] != self.memberId\n )\n \n idnormalizer = queryUtility(IIDNormalizer)\n- newNode[\'normalized_portal_type\'] = idnormalizer.normalize(portalType)\n- newNode[\'normalized_review_state\'] = idnormalizer.normalize(\n- newNode[\'review_state\']\n+ newNode["normalized_portal_type"] = idnormalizer.normalize(portalType)\n+ newNode["normalized_review_state"] = idnormalizer.normalize(\n+ newNode["review_state"]\n )\n- newNode[\'normalized_id\'] = idnormalizer.normalize(newNode[\'id\'])\n+ newNode["normalized_id"] = idnormalizer.normalize(newNode["id"])\n \n return newNode\n \n def showChildrenOf(self, object):\n- getTypeInfo = getattr(object, \'getTypeInfo\', None)\n+ getTypeInfo = getattr(object, "getTypeInfo", None)\n if getTypeInfo is not None:\n portal_type = getTypeInfo().getId()\n if portal_type in self.parentTypesNQ:\n@@ -195,8 +193,7 @@ def showChildrenOf(self, object):\n \n @implementer(INavtreeStrategy)\n class DefaultNavtreeStrategy(SitemapNavtreeStrategy):\n- """The navtree strategy used for the default navigation portlet\n- """\n+ """The navtree strategy used for the default navigation portlet"""\n \n def __init__(self, context, view=None):\n SitemapNavtreeStrategy.__init__(self, context, view)\n@@ -209,7 +206,7 @@ def subtreeFilter(self, node):\n sitemapDecision = SitemapNavtreeStrategy.subtreeFilter(self, node)\n if not sitemapDecision:\n return False\n- depth = node.get(\'depth\', 0)\n+ depth = node.get("depth", 0)\n if depth > 0 and self.bottomLevel > 0 and depth >= self.bottomLevel:\n return False\n return True\ndiff --git a/Products/CMFPlone/browser/okay.py b/Products/CMFPlone/browser/okay.py\nindex eeaae619ab..63c036a42d 100644\n--- a/Products/CMFPlone/browser/okay.py\n+++ b/Products/CMFPlone/browser/okay.py\n@@ -20,7 +20,7 @@ def __call__(self):\n # plone/app/caching/operations/utils.py does in the doNotCache\n # function.\n set_header = self.request.response.setHeader\n- set_header(\'Expires\', \'Sat, 1 Jan 2000 00:00:00 GMT\')\n- set_header(\'Cache-Control\', \'max-age=0, must-revalidate, private\')\n+ set_header("Expires", "Sat, 1 Jan 2000 00:00:00 GMT")\n+ set_header("Cache-Control", "max-age=0, must-revalidate, private")\n # Return a short and simple message.\n- return \'OK\'\n+ return "OK"\ndiff --git a/Products/CMFPlone/browser/ploneview.py b/Products/CMFPlone/browser/ploneview.py\nindex 4b4c5fe297..47c2bcd582 100644\n--- a/Products/CMFPlone/browser/ploneview.py\n+++ b/Products/CMFPlone/browser/ploneview.py\n@@ -18,7 +18,6 @@\n \n @implementer(IPlone)\n class Plone(BrowserView):\n-\n # Utility methods\n \n @memoize\ndiff --git a/Products/CMFPlone/browser/robots.py b/Products/CMFPlone/browser/robots.py\nindex a80557d91d..776ee8f009 100644\n--- a/Products/CMFPlone/browser/robots.py\n+++ b/Products/CMFPlone/browser/robots.py\n@@ -19,7 +19,8 @@ class Robots(BrowserView):\n \n def __call__(self):\n portal_state = getMultiAdapter(\n- (self.context, self.request), name=\'plone_portal_state\')\n+ (self.context, self.request), name="plone_portal_state"\n+ )\n portal_url = portal_state.portal_url()\n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISiteSchema, prefix="plone")\ndiff --git a/Products/CMFPlone/browser/search.py b/Products/CMFPlone/browser/search.py\nindex fa74d78782..956a5311ad 100644\n--- a/Products/CMFPlone/browser/search.py\n+++ b/Products/CMFPlone/browser/search.py\n@@ -20,37 +20,37 @@\n import re\n \n \n-_ = MessageFactory(\'plone\')\n+_ = MessageFactory("plone")\n \n # We should accept both a simple space, unicode u\'\\u0020 but also a\n # multi-space, so called \'waji-kankaku\', unicode u\'\\u3000\'\n-MULTISPACE = \'\\u3000\'\n-BAD_CHARS = (\'?\', \'-\', \'+\', \'*\', MULTISPACE)\n-EVER = DateTime(\'1970-01-03\')\n+MULTISPACE = "\\u3000"\n+BAD_CHARS = ("?", "-", "+", "*", MULTISPACE)\n+EVER = DateTime("1970-01-03")\n \n \n def quote_chars(s):\n # We need to quote parentheses when searching text indices\n- if \'(\' in s:\n- s = s.replace(\'(\', \'"("\')\n- if \')\' in s:\n- s = s.replace(\')\', \'")"\')\n+ if "(" in s:\n+ s = s.replace("(", \'"("\')\n+ if ")" in s:\n+ s = s.replace(")", \'")"\')\n if MULTISPACE in s:\n- s = s.replace(MULTISPACE, \' \')\n+ s = s.replace(MULTISPACE, " ")\n return s\n \n \n def quote(term):\n # The terms and, or and not must be wrapped in quotes to avoid\n # being parsed as logical query atoms.\n- if term.lower() in (\'and\', \'or\', \'not\'):\n+ if term.lower() in ("and", "or", "not"):\n term = \'"%s"\' % term\n return term\n \n \n def munge_search_term(query):\n for char in BAD_CHARS:\n- query = query.replace(char, \' \')\n+ query = query.replace(char, " ")\n \n # extract quoted phrases first\n quoted_phrases = re.findall(r\'"([^"]*)"\', query)\n@@ -67,31 +67,31 @@ def munge_search_term(query):\n \n r += map(quote, query.strip().split())\n r = " AND ".join(r)\n- r = quote_chars(r) + (\'*\' if r and not r.endswith(\'"\') else \'\')\n+ r = quote_chars(r) + ("*" if r and not r.endswith(\'"\') else "")\n return r\n \n \n class Search(BrowserView):\n+ valid_keys = ("sort_on", "sort_order", "sort_limit", "fq", "fl", "facet")\n \n- valid_keys = (\'sort_on\', \'sort_order\', \'sort_limit\', \'fq\', \'fl\', \'facet\')\n-\n- def results(self, query=None, batch=True, b_size=10, b_start=0,\n- use_content_listing=True):\n- """ Get properly wrapped search results from the catalog.\n+ def results(\n+ self, query=None, batch=True, b_size=10, b_start=0, use_content_listing=True\n+ ):\n+ """Get properly wrapped search results from the catalog.\n Everything in Plone that performs searches should go through this view.\n \'query\' should be a dictionary of catalog parameters.\n """\n if query is None:\n query = {}\n if batch:\n- query[\'b_start\'] = b_start = int(b_start)\n- query[\'b_size\'] = b_size\n+ query["b_start"] = b_start = int(b_start)\n+ query["b_size"] = b_size\n query = self.filter_query(query)\n \n if query is None:\n results = []\n else:\n- catalog = getToolByName(self.context, \'portal_catalog\')\n+ catalog = getToolByName(self.context, "portal_catalog")\n try:\n results = catalog(**query)\n except ParseError:\n@@ -106,55 +106,56 @@ def results(self, query=None, batch=True, b_size=10, b_start=0,\n def _filter_query(self, query):\n request = self.request\n \n- catalog = getToolByName(self.context, \'portal_catalog\')\n+ catalog = getToolByName(self.context, "portal_catalog")\n valid_indexes = tuple(catalog.indexes())\n valid_keys = self.valid_keys + valid_indexes\n \n- text = query.get(\'SearchableText\', None)\n+ text = query.get("SearchableText", None)\n if text is None:\n- text = request.form.get(\'SearchableText\', \'\')\n+ text = request.form.get("SearchableText", "")\n if not text:\n # Without text, must provide a meaningful non-empty search\n- valid = set(valid_indexes).intersection(request.form.keys()) or \\\n- set(valid_indexes).intersection(query.keys())\n+ valid = set(valid_indexes).intersection(request.form.keys()) or set(\n+ valid_indexes\n+ ).intersection(query.keys())\n if not valid:\n return\n \n for k, v in request.form.items():\n- if v and ((k in valid_keys) or k.startswith(\'facet.\')):\n+ if v and ((k in valid_keys) or k.startswith("facet.")):\n query[k] = v\n if text:\n- query[\'SearchableText\'] = munge_search_term(text)\n+ query["SearchableText"] = munge_search_term(text)\n \n # don\'t filter on created at all if we want all results\n- created = query.get(\'created\')\n+ created = query.get("created")\n if created:\n try:\n- if created.get(\'query\', EVER) <= EVER:\n- del query[\'created\']\n+ if created.get("query", EVER) <= EVER:\n+ del query["created"]\n except AttributeError:\n # created not a mapping\n- del query[\'created\']\n+ del query["created"]\n \n # respect `types_not_searched` setting\n- types = query.get(\'portal_type\', [])\n- if \'query\' in types:\n- types = types[\'query\']\n- query[\'portal_type\'] = self.filter_types(types)\n+ types = query.get("portal_type", [])\n+ if "query" in types:\n+ types = types["query"]\n+ query["portal_type"] = self.filter_types(types)\n # respect effective/expiration date\n- query[\'show_inactive\'] = False\n+ query["show_inactive"] = False\n # respect navigation root if we\'re not at the site root.\n- if \'path\' not in query and not IPloneSiteRoot.providedBy(self.context):\n- query[\'path\'] = getNavigationRoot(self.context)\n+ if "path" not in query and not IPloneSiteRoot.providedBy(self.context):\n+ query["path"] = getNavigationRoot(self.context)\n \n- if \'sort_order\' in query and not query[\'sort_order\']:\n- del query[\'sort_order\']\n+ if "sort_order" in query and not query["sort_order"]:\n+ del query["sort_order"]\n return query\n \n @lazy_property\n def default_sort_on(self):\n registry = getUtility(IRegistry)\n- search_settings = registry.forInterface(ISearchSchema, prefix=\'plone\')\n+ search_settings = registry.forInterface(ISearchSchema, prefix="plone")\n return search_settings.sort_on\n \n def filter_query(self, query):\n@@ -163,69 +164,67 @@ def filter_query(self, query):\n query = {}\n # explicitly set a sort; if no `sort_on` is present, the catalog sorts\n # by relevance\n- if \'sort_on\' not in query:\n+ if "sort_on" not in query:\n self.default_sort_on\n- if self.default_sort_on != \'relevance\':\n- query[\'sort_on\'] = self.default_sort_on\n- elif query[\'sort_on\'] == \'relevance\':\n- del query[\'sort_on\']\n- if query.get(\'sort_on\', \'\') == \'Date\':\n- query[\'sort_order\'] = \'reverse\'\n- elif \'sort_order\' in query:\n- del query[\'sort_order\']\n+ if self.default_sort_on != "relevance":\n+ query["sort_on"] = self.default_sort_on\n+ elif query["sort_on"] == "relevance":\n+ del query["sort_on"]\n+ if query.get("sort_on", "") == "Date":\n+ query["sort_order"] = "reverse"\n+ elif "sort_order" in query:\n+ del query["sort_order"]\n if not query:\n return None\n return query\n \n def filter_types(self, types):\n- plone_utils = getToolByName(self.context, \'plone_utils\')\n+ plone_utils = getToolByName(self.context, "plone_utils")\n if not isinstance(types, list):\n types = [types]\n return plone_utils.getUserFriendlyTypes(types)\n \n def types_list(self):\n # only show those types that have any content\n- catalog = getToolByName(self.context, \'portal_catalog\')\n- used_types = catalog._catalog.getIndex(\'portal_type\').uniqueValues()\n+ catalog = getToolByName(self.context, "portal_catalog")\n+ used_types = catalog._catalog.getIndex("portal_type").uniqueValues()\n return self.filter_types(list(used_types))\n \n def sort_options(self):\n- """ Sorting options for search results view. """\n- if \'sort_on\' not in self.request.form:\n- self.request.form[\'sort_on\'] = self.default_sort_on\n+ """Sorting options for search results view."""\n+ if "sort_on" not in self.request.form:\n+ self.request.form["sort_on"] = self.default_sort_on\n return (\n- SortOption(self.request, _(\'relevance\'), \'relevance\'),\n- SortOption(\n- self.request, _(\'date (newest first)\'), \'Date\', reverse=True\n- ),\n- SortOption(self.request, _(\'alphabetically\'), \'sortable_title\'),\n+ SortOption(self.request, _("relevance"), "relevance"),\n+ SortOption(self.request, _("date (newest first)"), "Date", reverse=True),\n+ SortOption(self.request, _("alphabetically"), "sortable_title"),\n )\n \n def show_advanced_search(self):\n """Whether we need to show advanced search options a.k.a. filters?"""\n- show = self.request.get(\'advanced_search\', None)\n- if not show or show == \'False\':\n+ show = self.request.get("advanced_search", None)\n+ if not show or show == "False":\n return False\n return True\n \n def advanced_search_trigger(self):\n """URL builder for show/close advanced search filters."""\n- query = self.request.get(\'QUERY_STRING\', None)\n- url = self.request.get(\'ACTUAL_URL\', self.context.absolute_url())\n+ query = self.request.get("QUERY_STRING", None)\n+ url = self.request.get("ACTUAL_URL", self.context.absolute_url())\n if not query:\n return url\n- if \'advanced_search\' in query:\n- if \'advanced_search=True\' in query:\n- query = query.replace(\'advanced_search=True\', \'\')\n- if \'advanced_search=False\' in query:\n- query = query.replace(\'advanced_search=False\', \'\')\n+ if "advanced_search" in query:\n+ if "advanced_search=True" in query:\n+ query = query.replace("advanced_search=True", "")\n+ if "advanced_search=False" in query:\n+ query = query.replace("advanced_search=False", "")\n else:\n- query = query + \'&advanced_search=True\'\n- return url + \'?\' + query\n+ query = query + "&advanced_search=True"\n+ return url + "?" + query\n \n def breadcrumbs(self, item):\n obj = item.getObject()\n- view = getMultiAdapter((obj, self.request), name=\'breadcrumbs_view\')\n+ view = getMultiAdapter((obj, self.request), name="breadcrumbs_view")\n # cut off the item itself\n breadcrumbs = list(view.breadcrumbs())[:-1]\n if len(breadcrumbs) == 0:\n@@ -233,37 +232,36 @@ def breadcrumbs(self, item):\n return None\n if len(breadcrumbs) > 3:\n # if we have too long breadcrumbs, emit the middle elements\n- empty = {\'absolute_url\': \'\', \'Title\': \'\xe2\x80\xa6\'}\n+ empty = {"absolute_url": "", "Title": "\xe2\x80\xa6"}\n breadcrumbs = [breadcrumbs[0], empty] + breadcrumbs[-2:]\n return breadcrumbs\n \n def navroot_url(self):\n- if not hasattr(self, \'_navroot_url\'):\n- state = self.context.unrestrictedTraverse(\'@@plone_portal_state\')\n+ if not hasattr(self, "_navroot_url"):\n+ state = self.context.unrestrictedTraverse("@@plone_portal_state")\n self._navroot_url = state.navigation_root_url()\n return self._navroot_url\n \n @property\n def show_images(self):\n registry = queryUtility(IRegistry)\n- return registry.get(\'plone.search_show_images\')\n+ return registry.get("plone.search_show_images")\n \n @property\n def search_image_scale(self):\n registry = queryUtility(IRegistry)\n- return registry.get(\'plone.search_image_scale\')\n+ return registry.get("plone.search_image_scale")\n \n \n class AjaxSearch(Search):\n-\n def __call__(self):\n items = []\n try:\n- per_page = int(self.request.form.get(\'perPage\'))\n+ per_page = int(self.request.form.get("perPage"))\n except:\n per_page = 10\n try:\n- page = int(self.request.form.get(\'page\'))\n+ page = int(self.request.form.get("page"))\n except:\n page = 1\n \n@@ -271,61 +269,60 @@ def __call__(self):\n batch = Batch(results, per_page, start=(page - 1) * per_page)\n \n registry = queryUtility(IRegistry)\n- length = registry.get(\'plone.search_results_description_length\')\n- show_images = registry.get(\'plone.search_show_images\')\n+ length = registry.get("plone.search_results_description_length")\n+ show_images = registry.get("plone.search_show_images")\n if show_images:\n- image_scale = registry.get(\'plone.search_image_scale\')\n+ image_scale = registry.get("plone.search_image_scale")\n # image_scaling = getMultiAdapter((self.context, self.request), name=\'image_scale\')\n- self.image_scaling = getMultiAdapter((INavigationRoot(self.context), self.request), name=\'image_scale\')\n- plone_view = getMultiAdapter(\n- (self.context, self.request), name=\'plone\')\n- view_action_types = registry.get(\n- \'plone.types_use_view_action_in_listings\', [])\n+ self.image_scaling = getMultiAdapter(\n+ (INavigationRoot(self.context), self.request), name="image_scale"\n+ )\n+ plone_view = getMultiAdapter((self.context, self.request), name="plone")\n+ view_action_types = registry.get("plone.types_use_view_action_in_listings", [])\n for item in batch:\n url = item.getURL()\n if item.portal_type in view_action_types:\n- url = \'%s/view\' % url\n+ url = "%s/view" % url\n img_tag = None\n if show_images:\n img_tag = self.get_image_tag(item, image_scale)\n- items.append({\n- \'id\': item.UID,\n- \'title\': item.Title,\n- \'description\': plone_view.cropText(item.Description, length),\n- \'url\': url,\n- \'state\': item.review_state if item.review_state else None,\n- \'img_tag\': img_tag,\n- })\n- return json.dumps({\n- \'total\': len(results),\n- \'items\': items\n- })\n+ items.append(\n+ {\n+ "id": item.UID,\n+ "title": item.Title,\n+ "description": plone_view.cropText(item.Description, length),\n+ "url": url,\n+ "state": item.review_state if item.review_state else None,\n+ "img_tag": img_tag,\n+ }\n+ )\n+ return json.dumps({"total": len(results), "items": items})\n \n def get_image_tag(self, item, image_scale):\n return self.image_scaling.tag(item, "image", scale=image_scale)\n \n-class SortOption:\n \n- def __init__(self, request, title, sortkey=\'\', reverse=False):\n+class SortOption:\n+ def __init__(self, request, title, sortkey="", reverse=False):\n self.request = request\n self.title = title\n self.sortkey = sortkey\n self.reverse = reverse\n \n def selected(self):\n- sort_on = self.request.get(\'sort_on\', \'\')\n- return sort_on == self.sortkey and sort_on != \'\'\n+ sort_on = self.request.get("sort_on", "")\n+ return sort_on == self.sortkey and sort_on != ""\n \n def url(self):\n q = {}\n q.update(self.request.form)\n- if \'sort_on\' in q.keys():\n- del q[\'sort_on\']\n- if \'sort_order\' in q.keys():\n- del q[\'sort_order\']\n- q[\'sort_on\'] = self.sortkey\n+ if "sort_on" in q.keys():\n+ del q["sort_on"]\n+ if "sort_order" in q.keys():\n+ del q["sort_order"]\n+ q["sort_on"] = self.sortkey\n if self.reverse:\n- q[\'sort_order\'] = \'reverse\'\n+ q["sort_order"] = "reverse"\n \n base_url = self.request.URL\n- return base_url + \'?\' + make_query(q)\n+ return base_url + "?" + make_query(q)\ndiff --git a/Products/CMFPlone/browser/sendto.py b/Products/CMFPlone/browser/sendto.py\nindex 95d63034a4..d3a6116036 100644\n--- a/Products/CMFPlone/browser/sendto.py\n+++ b/Products/CMFPlone/browser/sendto.py\n@@ -20,38 +20,37 @@\n \n \n class SendToForm(form.Form):\n- label = _(\'heading_send_page_to\',\n- default=\'Send this page to someone\')\n+ label = _("heading_send_page_to", default="Send this page to someone")\n \n- description = _(\'description_send_page_url_to\',\n- default=\'Fill in the email address of your \'\n- \'friend, and we will send an email \'\n- \'that contains a link to this page.\')\n+ description = _(\n+ "description_send_page_url_to",\n+ default="Fill in the email address of your "\n+ "friend, and we will send an email "\n+ "that contains a link to this page.",\n+ )\n \n fields = field.Fields(ISendToForm)\n ignoreContext = True\n \n- mail_template = ViewPageTemplateFile(\'templates/sendto_template.pt\')\n+ mail_template = ViewPageTemplateFile("templates/sendto_template.pt")\n \n- @button.buttonAndHandler(_(\'label_send\', default=\'Send\'),\n- name=\'send\')\n+ @button.buttonAndHandler(_("label_send", default="Send"), name="send")\n def handle_send(self, action):\n data, errors = self.extractData()\n if errors:\n IStatusMessage(self.request).addStatusMessage(\n- self.formErrorsMessage,\n- type=\'error\'\n+ self.formErrorsMessage, type="error"\n )\n return\n \n- send_from_address = data.get(\'send_from_address\')\n- send_to_address = data.get(\'send_to_address\')\n+ send_from_address = data.get("send_from_address")\n+ send_to_address = data.get("send_to_address")\n subject = pretty_title_or_id(self, self.context)\n title = pretty_title_or_id(self, self.context)\n description = self.context.Description()\n- comment = data.get(\'comment\', None)\n+ comment = data.get("comment", None)\n registry = getUtility(IRegistry)\n- mail_settings = registry.forInterface(IMailSchema, prefix=\'plone\')\n+ mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n envelope_from = mail_settings.email_from_address\n email_from_name = mail_settings.email_from_name\n \n@@ -59,7 +58,7 @@ def handle_send(self, action):\n # Sends a link of a page to someone.\n host = getUtility(IMailHost)\n registry = getUtility(IRegistry)\n- encoding = registry.get(\'plone.email_charset\', \'utf-8\')\n+ encoding = registry.get("plone.email_charset", "utf-8")\n \n if not envelope_from:\n envelope_from = send_from_address\n@@ -73,7 +72,7 @@ def handle_send(self, action):\n subject=subject,\n title=title,\n description=description,\n- email_from_name=email_from_name\n+ email_from_name=email_from_name,\n )\n \n message = message.encode(encoding)\n@@ -83,7 +82,7 @@ def handle_send(self, action):\n mto=send_to_address,\n mfrom=envelope_from,\n subject=subject,\n- charset=\'utf-8\'\n+ charset="utf-8",\n )\n \n except ConflictError:\n@@ -92,14 +91,11 @@ def handle_send(self, action):\n # TODO To many things could possibly go wrong. So we catch all.\n logger.info("Unable to send mail: " + str(e))\n IStatusMessage(self.request).addStatusMessage(\n- _(\'Unable to send mail.\'),\n- type=\'error\'\n+ _("Unable to send mail."), type="error"\n )\n return\n \n- IStatusMessage(self.request).addStatusMessage(\n- _(\'Mail sent.\'),\n- type=\'info\'\n- )\n+ IStatusMessage(self.request).addStatusMessage(_("Mail sent."), type="info")\n+\n \n send_to_form = layout.wrap_form(SendToForm)\ndiff --git a/Products/CMFPlone/browser/sitelogo.py b/Products/CMFPlone/browser/sitelogo.py\nindex cb816a6b48..2a4c954db0 100644\n--- a/Products/CMFPlone/browser/sitelogo.py\n+++ b/Products/CMFPlone/browser/sitelogo.py\n@@ -7,7 +7,6 @@\n \n \n class SiteLogo(Download):\n-\n def __init__(self, context, request):\n super().__init__(context, request)\n self.filename = None\n@@ -15,7 +14,7 @@ def __init__(self, context, request):\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISiteSchema, prefix="plone")\n- if getattr(settings, \'site_logo\', False):\n+ if getattr(settings, "site_logo", False):\n filename, data = b64decode_file(settings.site_logo)\n data = NamedImage(data=data, filename=filename)\n self.data = data\ndiff --git a/Products/CMFPlone/browser/sitemap.py b/Products/CMFPlone/browser/sitemap.py\nindex b835a89ea2..4628d6784c 100644\n--- a/Products/CMFPlone/browser/sitemap.py\n+++ b/Products/CMFPlone/browser/sitemap.py\n@@ -8,26 +8,25 @@\n \n @implementer(ISitemapView)\n class SitemapView(BrowserView):\n-\n- item_template = ViewPageTemplateFile(\'templates/sitemap-item.pt\')\n+ item_template = ViewPageTemplateFile("templates/sitemap-item.pt")\n \n def createSiteMap(self):\n context = aq_inner(self.context)\n- view = getMultiAdapter((context, self.request),\n- name=\'sitemap_builder_view\')\n+ view = getMultiAdapter((context, self.request), name="sitemap_builder_view")\n data = view.siteMap()\n- return self._renderLevel(children=data.get(\'children\', []))\n+ return self._renderLevel(children=data.get("children", []))\n \n def _renderLevel(self, children=[], level=2):\n- output = \'\'\n+ output = ""\n for node in children:\n output += \'\\n\'\n output += self.item_template(node=node)\n- children = node.get(\'children\', [])\n+ children = node.get("children", [])\n if len(children):\n- output += \\\n- \'\\n\' % (\n- level, self._renderLevel(children, level + 1))\n- output += \' \\n\'\n+ output += \'\\n\' % (\n+ level,\n+ self._renderLevel(children, level + 1),\n+ )\n+ output += "\\n"\n \n return output\ndiff --git a/Products/CMFPlone/browser/syndication/adapters.py b/Products/CMFPlone/browser/syndication/adapters.py\nindex aa7c48a47e..8cf927290e 100644\n--- a/Products/CMFPlone/browser/syndication/adapters.py\n+++ b/Products/CMFPlone/browser/syndication/adapters.py\n@@ -24,16 +24,16 @@\n \n \n class BaseFeedData:\n-\n def __init__(self, context):\n self.context = context\n self.settings = IFeedSettings(context)\n self.site = getSite()\n if self.show_about:\n- self.pm = getToolByName(self.context, \'portal_membership\')\n+ self.pm = getToolByName(self.context, "portal_membership")\n registry = getUtility(IRegistry)\n self.view_action_types = registry.get(\n- \'plone.types_use_view_action_in_listings\', [])\n+ "plone.types_use_view_action_in_listings", []\n+ )\n \n @lazy_property\n def show_about(self):\n@@ -50,7 +50,8 @@ def base_url(self):\n @lazy_property\n def canonical_url(self):\n pcs = getMultiAdapter(\n- (self.context, self.context.REQUEST), name=\'plone_context_state\')\n+ (self.context, self.context.REQUEST), name="plone_context_state"\n+ )\n return pcs.canonical_object_url()\n \n @property\n@@ -68,7 +69,7 @@ def categories(self):\n @property\n def published(self):\n date = self.context.EffectiveDate()\n- if date and date != \'None\':\n+ if date and date != "None":\n return DateTime(date)\n \n @property\n@@ -80,7 +81,7 @@ def modified(self):\n @property\n def uid(self):\n uuid = IUUID(self.context, None)\n- if uuid is None and hasattr(self.context, \'UID\'):\n+ if uuid is None and hasattr(self.context, "UID"):\n return self.context.UID()\n return uuid\n \n@@ -90,14 +91,13 @@ def rights(self):\n \n @property\n def publisher(self):\n- if hasattr(self.context, \'Publisher\'):\n+ if hasattr(self.context, "Publisher"):\n return self.context.Publisher()\n- return \'No Publisher\'\n+ return "No Publisher"\n \n \n @implementer(IFeed)\n class FolderFeed(BaseFeedData):\n-\n @lazy_property\n def author(self):\n if self.show_about:\n@@ -108,12 +108,12 @@ def author(self):\n @property\n def author_name(self):\n if self.author:\n- return self.author.getProperty(\'fullname\')\n+ return self.author.getProperty("fullname")\n \n @property\n def author_email(self):\n if self.author:\n- return self.author.getProperty(\'email\')\n+ return self.author.getProperty("email")\n \n @property\n def logo(self):\n@@ -121,14 +121,13 @@ def logo(self):\n \n @property\n def icon(self):\n- return \'%s/favicon.ico\' % self.site.absolute_url()\n+ return "%s/favicon.ico" % self.site.absolute_url()\n \n def _brains(self):\n- catalog = getToolByName(self.context, \'portal_catalog\')\n- return catalog(path={\n- \'query\': \'/\'.join(self.context.getPhysicalPath()),\n- \'depth\': 1\n- })\n+ catalog = getToolByName(self.context, "portal_catalog")\n+ return catalog(\n+ path={"query": "/".join(self.context.getPhysicalPath()), "depth": 1}\n+ )\n \n def _items(self):\n """\n@@ -138,7 +137,7 @@ def _items(self):\n \n @property\n def items(self):\n- for item in self._items()[:self.limit]:\n+ for item in self._items()[: self.limit]:\n # look for custom adapter\n # otherwise, just use default\n adapter = queryMultiAdapter((item, self), IFeedItem)\n@@ -152,29 +151,27 @@ def limit(self):\n \n @property\n def language(self):\n- langtool = getToolByName(self.context, \'portal_languages\')\n+ langtool = getToolByName(self.context, "portal_languages")\n return langtool.getDefaultLanguage()\n \n \n class CollectionFeed(FolderFeed):\n-\n def _brains(self):\n- return self.context.queryCatalog(batch=False)[:self.limit]\n+ return self.context.queryCatalog(batch=False)[: self.limit]\n \n \n @implementer(ISearchFeed)\n class SearchFeed(FolderFeed):\n-\n def _brains(self):\n max_items = self.limit\n request = self.context.REQUEST\n- start = int(request.get(\'b_start\', 0))\n- end = int(request.get(\'b_end\', start + max_items))\n- request.set(\'sort_order\', \'reverse\')\n- request.set(\'sort_on\', request.get(\'sort_on\', \'effective\'))\n+ start = int(request.get("b_start", 0))\n+ end = int(request.get("b_end", start + max_items))\n+ request.set("sort_order", "reverse")\n+ request.set("sort_on", request.get("sort_on", "effective"))\n return self.context.queryCatalog(\n- show_all=1, use_types_blacklist=True,\n- use_navigation_root=True)[start:end]\n+ show_all=1, use_types_blacklist=True, use_navigation_root=True\n+ )[start:end]\n \n \n @implementer(IFeedItem)\n@@ -187,7 +184,7 @@ def __init__(self, context, feed):\n \n @lazy_property\n def creator(self):\n- if hasattr(self.context, \'Creator\'):\n+ if hasattr(self.context, "Creator"):\n return self.context.Creator()\n \n @lazy_property\n@@ -195,30 +192,30 @@ def author(self):\n if self.feed.show_about:\n creator = self.context.Creator()\n member = self.feed.pm.getMemberById(creator)\n- return member and member.getProperty(\'fullname\') or creator\n+ return member and member.getProperty("fullname") or creator\n \n @property\n def author_name(self):\n author = self.author\n- if author and hasattr(author, \'getProperty\'):\n- return author.getProperty(\'fullname\')\n+ if author and hasattr(author, "getProperty"):\n+ return author.getProperty("fullname")\n \n @property\n def author_email(self):\n author = self.author\n- if author and hasattr(author, \'getProperty\'):\n- return author.getProperty(\'email\')\n+ if author and hasattr(author, "getProperty"):\n+ return author.getProperty("email")\n \n @property\n def body(self):\n- if hasattr(self.context, \'getText\'):\n+ if hasattr(self.context, "getText"):\n value = self.context.getText()\n- elif hasattr(self.context, \'text\'):\n+ elif hasattr(self.context, "text"):\n value = self.context.text\n else:\n value = self.description\n if not isinstance(value, str):\n- if hasattr(value, \'output\'):\n+ if hasattr(value, "output"):\n # could be RichTextValue object, needs transform\n value = value.output\n return value\n@@ -233,7 +230,7 @@ def render_content_core(self):\n def link(self):\n url = self.base_url\n if self.context.portal_type in self.feed.view_action_types:\n- url = url + \'/view\'\n+ url = url + "/view"\n else:\n url = self.canonical_url\n return url\n@@ -256,7 +253,7 @@ def file_url(self):\n if fi is not None:\n filename = fi.getFilename()\n if filename:\n- url += \'/@@download/file/%s\' % filename\n+ url += "/@@download/file/%s" % filename\n return url\n \n @property\n@@ -272,24 +269,28 @@ class DexterityItem(BaseItem):\n adapts(IDexterityContent, IFeed)\n \n file = None\n- field_name = \'\'\n+ field_name = ""\n \n def __init__(self, context, feed):\n super().__init__(context, feed)\n self.dexterity = IDexterityContent.providedBy(context)\n lead = ILeadImage(self.context, None)\n if lead:\n- if (lead.image\n- and hasattr(lead.image, \'getSize\')\n- and lead.image.getSize() > 0):\n+ if (\n+ lead.image\n+ and hasattr(lead.image, "getSize")\n+ and lead.image.getSize() > 0\n+ ):\n self.file = lead.image\n- self.field_name = \'image\'\n+ self.field_name = "image"\n if self.file is None:\n try:\n primary = IPrimaryFieldInfo(self.context, None)\n- if (INamedField.providedBy(primary.field)\n- and hasattr(primary.value, \'getSize\')\n- and primary.value.getSize() > 0):\n+ if (\n+ INamedField.providedBy(primary.field)\n+ and hasattr(primary.value, "getSize")\n+ and primary.value.getSize() > 0\n+ ):\n self.file = primary.value\n self.field_name = primary.fieldname\n except TypeError:\n@@ -302,8 +303,7 @@ def file_url(self):\n if fi is not None:\n filename = fi.filename\n if filename:\n- url += \'/@@download/{}/{}\'.format(\n- self.field_name, filename)\n+ url += "/@@download/{}/{}".format(self.field_name, filename)\n return url\n \n @property\ndiff --git a/Products/CMFPlone/browser/syndication/settings.py b/Products/CMFPlone/browser/syndication/settings.py\nindex da4daca293..179f55e6f0 100644\n--- a/Products/CMFPlone/browser/syndication/settings.py\n+++ b/Products/CMFPlone/browser/syndication/settings.py\n@@ -9,7 +9,7 @@\n from zope.interface import implementer\n \n \n-FEED_SETTINGS_KEY = \'syndication_settings\'\n+FEED_SETTINGS_KEY = "syndication_settings"\n \n \n @implementer(IFeedSettings)\n@@ -27,8 +27,9 @@ def __init__(self, context):\n self.needs_saving = True\n \n registry = getUtility(IRegistry)\n- self.site_settings = registry.forInterface(ISiteSyndicationSettings,\n- check=False)\n+ self.site_settings = registry.forInterface(\n+ ISiteSyndicationSettings, check=False\n+ )\n \n def _set(self):\n """\n@@ -40,8 +41,13 @@ def _set(self):\n self.annotations[FEED_SETTINGS_KEY] = self._metadata\n \n def __setattr__(self, name, value):\n- if name in (\'context\', \'_metadata\', \'site_settings\', \'annotations\',\n- \'needs_saving\'):\n+ if name in (\n+ "context",\n+ "_metadata",\n+ "site_settings",\n+ "annotations",\n+ "needs_saving",\n+ ):\n self.__dict__[name] = value\n else:\n self._metadata[name] = value\n@@ -51,7 +57,7 @@ def __getattr__(self, name):\n default = None\n if name in ISiteSyndicationSettings.names():\n default = getattr(self.site_settings, name)\n- elif name == \'enabled\' and self.site_settings.default_enabled:\n+ elif name == "enabled" and self.site_settings.default_enabled:\n default = True\n elif name in IFeedSettings.names():\n default = IFeedSettings[name].default\ndiff --git a/Products/CMFPlone/browser/syndication/tool.py b/Products/CMFPlone/browser/syndication/tool.py\nindex 94a93823e0..b94456229b 100644\n--- a/Products/CMFPlone/browser/syndication/tool.py\n+++ b/Products/CMFPlone/browser/syndication/tool.py\n@@ -22,8 +22,14 @@ class SyndicationTool:\n backwards compatibility.\n """\n \n- def editProperties(self, updatePeriod=None, updateFrequency=None,\n- updateBase=None, isAllowed=None, max_items=None):\n+ def editProperties(\n+ self,\n+ updatePeriod=None,\n+ updateFrequency=None,\n+ updateBase=None,\n+ isAllowed=None,\n+ max_items=None,\n+ ):\n """\n Edit the properties for the SystemWide defaults on the\n SyndicationTool.\n@@ -78,4 +84,5 @@ def disableSyndication(self, obj):\n settings = IFeedSettings(obj)\n settings.enabled = False\n \n-registerToolInterface(\'portal_syndication\', ISyndicationTool)\n+\n+registerToolInterface("portal_syndication", ISyndicationTool)\ndiff --git a/Products/CMFPlone/browser/syndication/utils.py b/Products/CMFPlone/browser/syndication/utils.py\nindex 2fac9a8d9b..4d50da66c5 100644\n--- a/Products/CMFPlone/browser/syndication/utils.py\n+++ b/Products/CMFPlone/browser/syndication/utils.py\n@@ -13,16 +13,16 @@\n \n @implementer(ISyndicationUtil)\n class SyndicationUtil(BrowserView):\n-\n def allowed_feed_types(self):\n settings = IFeedSettings(self.context)\n- factory = getUtility(IVocabularyFactory,\n- "plone.app.vocabularies.SyndicationFeedTypes")\n+ factory = getUtility(\n+ IVocabularyFactory, "plone.app.vocabularies.SyndicationFeedTypes"\n+ )\n vocabulary = factory(self.context)\n types = []\n for typ in settings.feed_types:\n types.append(vocabulary.getTerm(typ))\n- return [{\'path\': t.value, \'title\': t.title} for t in types]\n+ return [{"path": t.value, "title": t.title} for t in types]\n \n def rss_url(self):\n settings = IFeedSettings(self.context)\n@@ -31,7 +31,7 @@ def rss_url(self):\n if len(types) == 0:\n return url\n _type = types[0]\n- return f\'{url}/{_type}\'\n+ return f"{url}/{_type}"\n \n def context_allowed(self):\n if not ISyndicatable.providedBy(self.context):\ndiff --git a/Products/CMFPlone/browser/syndication/views.py b/Products/CMFPlone/browser/syndication/views.py\nindex e1e0969cc5..f165c80024 100644\n--- a/Products/CMFPlone/browser/syndication/views.py\n+++ b/Products/CMFPlone/browser/syndication/views.py\n@@ -17,8 +17,7 @@\n \n \n class FeedView(BrowserView):\n-\n- content_type = \'application/atom+xml\'\n+ content_type = "application/atom+xml"\n \n def feed(self):\n f = queryAdapter(self.context, IFeed)\n@@ -27,20 +26,19 @@ def feed(self):\n return f\n \n def __call__(self):\n- util = getMultiAdapter((self.context, self.request),\n- name=\'syndication-util\')\n- context_state = getMultiAdapter((self.context, self.request),\n- name=\'plone_context_state\')\n+ util = getMultiAdapter((self.context, self.request), name="syndication-util")\n+ context_state = getMultiAdapter(\n+ (self.context, self.request), name="plone_context_state"\n+ )\n if context_state.is_portal_root() or util.context_enabled(raise404=True):\n settings = IFeedSettings(self.context)\n if self.__name__ not in settings.feed_types:\n raise NotFound\n- self.request.response.setHeader(\'Content-Type\', self.content_type)\n+ self.request.response.setHeader("Content-Type", self.content_type)\n return self.index()\n \n \n class SearchFeedView(FeedView):\n-\n def feed(self):\n f = queryAdapter(self.context, ISearchFeed)\n if f is None:\n@@ -48,16 +46,14 @@ def feed(self):\n return f\n \n def __call__(self):\n- util = getMultiAdapter((self.context, self.request),\n- name=\'syndication-util\')\n+ util = getMultiAdapter((self.context, self.request), name="syndication-util")\n if util.search_rss_enabled(raise404=True):\n- self.request.response.setHeader(\'Content-Type\',\n- \'application/atom+xml\')\n+ self.request.response.setHeader("Content-Type", "application/atom+xml")\n return self.index()\n \n \n class NewsMLFeedView(FeedView):\n- content_type = \'application/vnd.iptc.g2.newsitem+xml\'\n+ content_type = "application/vnd.iptc.g2.newsitem+xml"\n \n @lazy_property\n def current_date(self):\n@@ -68,26 +64,25 @@ def duid(self, item, value):\n return uid.hex\n \n def get_image(self, item):\n- scales = item.context.restrictedTraverse(\'@@images\')\n+ scales = item.context.restrictedTraverse("@@images")\n if scales:\n try:\n- return scales.scale(\'image\')\n+ return scales.scale("image")\n except AttributeError:\n pass\n return None\n \n \n class SettingsForm(form.EditForm):\n- label = _(\'heading_syndication_properties\',\n- default=\'Syndication Properties\')\n+ label = _("heading_syndication_properties", default="Syndication Properties")\n description = _(\n- \'description_syndication_properties\',\n- default=\'Syndication enables you to syndicate this folder so it can\'\n- \'be synchronized from other web sites.\',\n+ "description_syndication_properties",\n+ default="Syndication enables you to syndicate this folder so it can"\n+ "be synchronized from other web sites.",\n )\n fields = field.Fields(IFeedSettings)\n \n- @button.buttonAndHandler(_(\'Save\'), name=\'save\')\n+ @button.buttonAndHandler(_("Save"), name="save")\n def handleSave(self, action):\n data, errors = self.extractData()\n if errors:\ndiff --git a/Products/CMFPlone/browser/test_rendering.py b/Products/CMFPlone/browser/test_rendering.py\nindex b4c42e9cc0..2864227d86 100644\n--- a/Products/CMFPlone/browser/test_rendering.py\n+++ b/Products/CMFPlone/browser/test_rendering.py\n@@ -3,30 +3,27 @@\n \n \n class TestRenderingView(BrowserView):\n-\n- template = ViewPageTemplateFile(\'templates/test_rendering.pt\')\n+ template = ViewPageTemplateFile("templates/test_rendering.pt")\n \n def __call__(self):\n- self.request.set(\'disable_plone.rightcolumn\', 1)\n- self.request.set(\'disable_plone.leftcolumn\', 1)\n+ self.request.set("disable_plone.rightcolumn", 1)\n+ self.request.set("disable_plone.leftcolumn", 1)\n return self.template()\n \n \n class TestRenderingCheatsheetView(BrowserView):\n-\n- template = ViewPageTemplateFile(\'templates/test_rendering_cheatsheet.pt\')\n+ template = ViewPageTemplateFile("templates/test_rendering_cheatsheet.pt")\n \n def __call__(self):\n- self.request.set(\'disable_plone.rightcolumn\', 1)\n- self.request.set(\'disable_plone.leftcolumn\', 1)\n+ self.request.set("disable_plone.rightcolumn", 1)\n+ self.request.set("disable_plone.leftcolumn", 1)\n return self.template()\n \n \n class TestRenderingIconsView(BrowserView):\n-\n- template = ViewPageTemplateFile(\'templates/test_rendering_icons.pt\')\n+ template = ViewPageTemplateFile("templates/test_rendering_icons.pt")\n \n def __call__(self):\n- self.request.set(\'disable_plone.rightcolumn\', 1)\n- self.request.set(\'disable_plone.leftcolumn\', 1)\n+ self.request.set("disable_plone.rightcolumn", 1)\n+ self.request.set("disable_plone.leftcolumn", 1)\n return self.template()\ndiff --git a/Products/CMFPlone/controlpanel/bbb/editing.py b/Products/CMFPlone/controlpanel/bbb/editing.py\nindex f5614a8cd9..c3feaacd46 100644\n--- a/Products/CMFPlone/controlpanel/bbb/editing.py\n+++ b/Products/CMFPlone/controlpanel/bbb/editing.py\n@@ -8,12 +8,11 @@\n \n @implementer(IEditingSchema)\n class EditingControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(IEditingSchema, prefix=\'plone\')\n+ self.settings = registry.forInterface(IEditingSchema, prefix="plone")\n \n def get_visible_ids(self):\n return self.settings.visible_ids\n@@ -47,8 +46,7 @@ def set_lock_on_ttw_edit(self, value):\n \n visible_ids = property(get_visible_ids, set_visible_ids)\n enable_link_integrity_checks = property(\n- get_enable_link_integrity_checks,\n- set_enable_link_integrity_checks\n+ get_enable_link_integrity_checks, set_enable_link_integrity_checks\n )\n ext_editor = property(get_ext_editor, set_ext_editor)\n default_editor = property(get_default_editor, set_default_editor)\ndiff --git a/Products/CMFPlone/controlpanel/bbb/filter.py b/Products/CMFPlone/controlpanel/bbb/filter.py\nindex 2da1d3dcb5..bd96a3d563 100644\n--- a/Products/CMFPlone/controlpanel/bbb/filter.py\n+++ b/Products/CMFPlone/controlpanel/bbb/filter.py\n@@ -8,12 +8,11 @@\n \n @implementer(IFilterSchema)\n class FilterControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(IFilterSchema, prefix=\'plone\')\n+ self.settings = registry.forInterface(IFilterSchema, prefix="plone")\n \n def get_disable_filtering(self):\n return self.settings.disable_filtering\n@@ -39,8 +38,7 @@ def get_custom_attributes(self):\n def set_custom_attributes(self, value):\n self.settings.custom_attributes = value\n \n- custom_attributes = property(\n- get_custom_attributes, set_custom_attributes)\n+ custom_attributes = property(get_custom_attributes, set_custom_attributes)\n valid_tags = property(get_valid_tags, set_valid_tags)\n nasty_tags = property(get_nasty_tags, set_nasty_tags)\n disable_filtering = property(get_disable_filtering, set_disable_filtering)\ndiff --git a/Products/CMFPlone/controlpanel/bbb/language.py b/Products/CMFPlone/controlpanel/bbb/language.py\nindex 8085b28cfb..56569adf91 100644\n--- a/Products/CMFPlone/controlpanel/bbb/language.py\n+++ b/Products/CMFPlone/controlpanel/bbb/language.py\n@@ -8,14 +8,12 @@\n \n @implementer(ILanguageSchema)\n class LanguageControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n self.context = context\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ILanguageSchema, prefix="plone")\n+ self.settings = registry.forInterface(ILanguageSchema, prefix="plone")\n \n def get_default_language(self):\n return self.settings.default_language\n@@ -23,8 +21,7 @@ def get_default_language(self):\n def set_default_language(self, value):\n self.settings.default_language = value\n \n- default_language = property(get_default_language,\n- set_default_language)\n+ default_language = property(get_default_language, set_default_language)\n \n def get_available_languages(self):\n return self.settings.available_languages\n@@ -32,8 +29,7 @@ def get_available_languages(self):\n def set_available_languages(self, value):\n self.settings.available_languages = value\n \n- available_languages = property(get_available_languages,\n- set_available_languages)\n+ available_languages = property(get_available_languages, set_available_languages)\n \n def get_use_combined_language_codes(self):\n return self.settings.use_combined_language_codes\n@@ -41,8 +37,9 @@ def get_use_combined_language_codes(self):\n def set_use_combined_language_codes(self, value):\n self.settings.use_combined_language_codes = value\n \n- use_combined_language_codes = property(get_use_combined_language_codes,\n- set_use_combined_language_codes)\n+ use_combined_language_codes = property(\n+ get_use_combined_language_codes, set_use_combined_language_codes\n+ )\n \n def get_display_flags(self):\n return self.settings.display_flags\n@@ -50,8 +47,7 @@ def get_display_flags(self):\n def set_display_flags(self, value):\n self.settings.display_flags = value\n \n- display_flags = property(get_display_flags,\n- set_display_flags)\n+ display_flags = property(get_display_flags, set_display_flags)\n \n def get_always_show_selector(self):\n return self.settings.always_show_selector\n@@ -59,8 +55,7 @@ def get_always_show_selector(self):\n def set_always_show_selector(self, value):\n self.settings.always_show_selector = value\n \n- always_show_selector = property(get_always_show_selector,\n- set_always_show_selector)\n+ always_show_selector = property(get_always_show_selector, set_always_show_selector)\n \n def get_use_content_negotiation(self):\n return self.settings.use_content_negotiation\n@@ -68,8 +63,9 @@ def get_use_content_negotiation(self):\n def set_use_content_negotiation(self, value):\n self.settings.use_content_negotiation = value\n \n- use_content_negotiation = property(get_use_content_negotiation,\n- set_use_content_negotiation)\n+ use_content_negotiation = property(\n+ get_use_content_negotiation, set_use_content_negotiation\n+ )\n \n def get_use_path_negotiation(self):\n return self.settings.use_path_negotiation\n@@ -77,8 +73,7 @@ def get_use_path_negotiation(self):\n def set_use_path_negotiation(self, value):\n self.settings.use_path_negotiation = value\n \n- use_path_negotiation = property(get_use_path_negotiation,\n- set_use_path_negotiation)\n+ use_path_negotiation = property(get_use_path_negotiation, set_use_path_negotiation)\n \n def get_use_cookie_negotiation(self):\n return self.settings.use_cookie_negotiation\n@@ -86,8 +81,9 @@ def get_use_cookie_negotiation(self):\n def set_use_cookie_negotiation(self, value):\n self.settings.use_cookie_negotiation = value\n \n- use_cookie_negotiation = property(get_use_cookie_negotiation,\n- set_use_cookie_negotiation)\n+ use_cookie_negotiation = property(\n+ get_use_cookie_negotiation, set_use_cookie_negotiation\n+ )\n \n def get_authenticated_users_only(self):\n return self.settings.authenticated_users_only\n@@ -95,8 +91,9 @@ def get_authenticated_users_only(self):\n def set_authenticated_users_only(self, value):\n self.settings.authenticated_users_only = value\n \n- authenticated_users_only = property(get_authenticated_users_only,\n- set_authenticated_users_only)\n+ authenticated_users_only = property(\n+ get_authenticated_users_only, set_authenticated_users_only\n+ )\n \n def get_set_cookie_always(self):\n return self.settings.set_cookie_always\n@@ -104,8 +101,7 @@ def get_set_cookie_always(self):\n def set_set_cookie_always(self, value):\n self.settings.set_cookie_always = value\n \n- set_cookie_always = property(get_set_cookie_always,\n- set_set_cookie_always)\n+ set_cookie_always = property(get_set_cookie_always, set_set_cookie_always)\n \n def get_use_subdomain_negotiation(self):\n return self.settings.use_subdomain_negotiation\n@@ -113,8 +109,9 @@ def get_use_subdomain_negotiation(self):\n def set_use_subdomain_negotiation(self, value):\n self.settings.use_subdomain_negotiation = value\n \n- use_subdomain_negotiation = property(get_use_subdomain_negotiation,\n- set_use_subdomain_negotiation)\n+ use_subdomain_negotiation = property(\n+ get_use_subdomain_negotiation, set_use_subdomain_negotiation\n+ )\n \n def get_use_cctld_negotiation(self):\n return self.settings.use_cctld_negotiation\n@@ -122,8 +119,9 @@ def get_use_cctld_negotiation(self):\n def set_use_cctld_negotiation(self, value):\n self.settings.use_cctld_negotiation = value\n \n- use_cctld_negotiation = property(get_use_cctld_negotiation,\n- set_use_cctld_negotiation)\n+ use_cctld_negotiation = property(\n+ get_use_cctld_negotiation, set_use_cctld_negotiation\n+ )\n \n def get_use_request_negotiation(self):\n return self.settings.use_request_negotiation\n@@ -131,5 +129,6 @@ def get_use_request_negotiation(self):\n def set_use_request_negotiation(self, value):\n self.settings.use_request_negotiation = value\n \n- use_request_negotiation = property(get_use_request_negotiation,\n- set_use_request_negotiation)\n+ use_request_negotiation = property(\n+ get_use_request_negotiation, set_use_request_negotiation\n+ )\ndiff --git a/Products/CMFPlone/controlpanel/bbb/mail.py b/Products/CMFPlone/controlpanel/bbb/mail.py\nindex 15ab993922..f1c89d8682 100644\n--- a/Products/CMFPlone/controlpanel/bbb/mail.py\n+++ b/Products/CMFPlone/controlpanel/bbb/mail.py\n@@ -10,63 +10,67 @@\n \n @implementer(IMailSchema)\n class MailControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n self.context = context\n self.portal = getSite()\n registry = getUtility(IRegistry)\n- self.encoding = \'utf-8\'\n- self.mail_settings = registry.forInterface(\n- IMailSchema, prefix="plone")\n+ self.encoding = "utf-8"\n+ self.mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n \n def get_smtp_host(self):\n return self.mail_settings.smtp_host\n \n def set_smtp_host(self, value):\n- if safe_hasattr(self.mail_settings, \'smtp_host\'):\n+ if safe_hasattr(self.mail_settings, "smtp_host"):\n self.mail_settings.smtp_host = value\n \n smtp_host = property(get_smtp_host, set_smtp_host)\n \n def get_smtp_port(self):\n- return getattr(self.mail_settings, \'smtp_port\', None)\n+ return getattr(self.mail_settings, "smtp_port", None)\n \n def set_smtp_port(self, value):\n- if safe_hasattr(self.mail_settings, \'smtp_port\'):\n+ if safe_hasattr(self.mail_settings, "smtp_port"):\n self.mail_settings.smtp_port = value\n \n smtp_port = property(get_smtp_port, set_smtp_port)\n \n def get_smtp_userid(self):\n- return getattr(self.mail_settings, \'smtp_userid\',\n- getattr(self.mail_settings, \'smtp_userid\', None))\n+ return getattr(\n+ self.mail_settings,\n+ "smtp_userid",\n+ getattr(self.mail_settings, "smtp_userid", None),\n+ )\n \n def set_smtp_userid(self, value):\n- if safe_hasattr(self.mail_settings, \'smtp_userid\'):\n+ if safe_hasattr(self.mail_settings, "smtp_userid"):\n self.mail_settings.smtp_userid = value\n # SecureMailhost 1.x also uses this:\n- if safe_hasattr(self.mail_settings, \'_smtp_userid\'):\n+ if safe_hasattr(self.mail_settings, "_smtp_userid"):\n self.mail_settings._smtp_userid = value\n- elif safe_hasattr(self.mail_settings, \'smtp_userid\'):\n+ elif safe_hasattr(self.mail_settings, "smtp_userid"):\n self.mail_settings.smtp_uid = value\n \n smtp_userid = property(get_smtp_userid, set_smtp_userid)\n \n def get_smtp_pass(self):\n- return getattr(self.mail_settings, \'smtp_pass\',\n- getattr(self.mail_settings, \'smtp_pwd\', None))\n+ return getattr(\n+ self.mail_settings,\n+ "smtp_pass",\n+ getattr(self.mail_settings, "smtp_pwd", None),\n+ )\n \n def set_smtp_pass(self, value):\n # Don\'t update the value, if we don\'t get a new one\n if value is not None:\n- if safe_hasattr(self.mail_settings, \'smtp_pass\'):\n+ if safe_hasattr(self.mail_settings, "smtp_pass"):\n self.mail_settings.smtp_pass = value\n # SecureMailhost 1.x also uses this:\n- if safe_hasattr(self.mail_settings, \'_smtp_pass\'):\n+ if safe_hasattr(self.mail_settings, "_smtp_pass"):\n self.mail_settings._smtp_pass = value\n- elif safe_hasattr(self.mail_settings, \'smtp_pwd\'):\n+ elif safe_hasattr(self.mail_settings, "smtp_pwd"):\n self.mail_settings.smtp_pwd = value\n \n smtp_pass = property(get_smtp_pass, set_smtp_pass)\n@@ -85,5 +89,4 @@ def get_email_from_address(self):\n def set_email_from_address(self, value):\n self.mail_settings.email_from_address = value\n \n- email_from_address = property(get_email_from_address,\n- set_email_from_address)\n+ email_from_address = property(get_email_from_address, set_email_from_address)\ndiff --git a/Products/CMFPlone/controlpanel/bbb/maintenance.py b/Products/CMFPlone/controlpanel/bbb/maintenance.py\nindex 941fea458b..500008a2a0 100644\n--- a/Products/CMFPlone/controlpanel/bbb/maintenance.py\n+++ b/Products/CMFPlone/controlpanel/bbb/maintenance.py\n@@ -8,14 +8,14 @@\n \n @implementer(IMaintenanceSchema)\n class MaintenanceControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n self.context = context\n registry = getUtility(IRegistry)\n self.maintenance_settings = registry.forInterface(\n- IMaintenanceSchema, prefix="plone")\n+ IMaintenanceSchema, prefix="plone"\n+ )\n \n def get_days(self):\n return self.maintenance_settings.days\ndiff --git a/Products/CMFPlone/controlpanel/bbb/markup.py b/Products/CMFPlone/controlpanel/bbb/markup.py\nindex 2434f6b84b..1f9814a3b7 100644\n--- a/Products/CMFPlone/controlpanel/bbb/markup.py\n+++ b/Products/CMFPlone/controlpanel/bbb/markup.py\n@@ -8,7 +8,6 @@\n \n @implementer(IMarkupSchema)\n class MarkupControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\ndiff --git a/Products/CMFPlone/controlpanel/bbb/navigation.py b/Products/CMFPlone/controlpanel/bbb/navigation.py\nindex 05705ccb77..f6ed1860c9 100644\n--- a/Products/CMFPlone/controlpanel/bbb/navigation.py\n+++ b/Products/CMFPlone/controlpanel/bbb/navigation.py\n@@ -9,13 +9,11 @@\n @adapter(IPloneSiteRoot)\n @implementer(INavigationSchema)\n class NavigationControlPanelAdapter:\n-\n def __init__(self, context):\n self.context = context\n registry = getUtility(IRegistry)\n self.navigation_settings = registry.forInterface(\n- INavigationSchema,\n- prefix="plone"\n+ INavigationSchema, prefix="plone"\n )\n \n def get_generate_tabs(self):\n@@ -40,10 +38,7 @@ def get_show_excluded_items(self):\n def set_show_excluded_items(self, value):\n self.navigation_settings.show_excluded_items = value\n \n- show_excluded_items = property(\n- get_show_excluded_items,\n- set_show_excluded_items\n- )\n+ show_excluded_items = property(get_show_excluded_items, set_show_excluded_items)\n \n def get_displayed_types(self):\n return self.navigation_settings.displayed_types\n@@ -59,10 +54,7 @@ def get_filter_on_workflow(self):\n def set_filter_on_workflow(self, value):\n self.navigation_settings.filter_on_workflow = value\n \n- filter_on_workflow = property(\n- get_filter_on_workflow,\n- set_filter_on_workflow\n- )\n+ filter_on_workflow = property(get_filter_on_workflow, set_filter_on_workflow)\n \n def get_workflow_states_to_show(self):\n return self.navigation_settings.workflow_states_to_show\n@@ -71,8 +63,8 @@ def set_workflow_states_to_show(self, value):\n self.navigation_settings.workflow_states_to_show = value\n \n workflow_states_to_show = property(\n- get_workflow_states_to_show,\n- set_workflow_states_to_show)\n+ get_workflow_states_to_show, set_workflow_states_to_show\n+ )\n \n @property\n def root(self):\ndiff --git a/Products/CMFPlone/controlpanel/bbb/search.py b/Products/CMFPlone/controlpanel/bbb/search.py\nindex 784a30d448..9f0562ad68 100644\n--- a/Products/CMFPlone/controlpanel/bbb/search.py\n+++ b/Products/CMFPlone/controlpanel/bbb/search.py\n@@ -9,14 +9,12 @@\n \n @implementer(ISearchSchema)\n class SearchControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n self.portal = getSite()\n registry = getUtility(IRegistry)\n- self.search_settings = registry.forInterface(\n- ISearchSchema, prefix="plone")\n+ self.search_settings = registry.forInterface(ISearchSchema, prefix="plone")\n \n def get_enable_livesearch(self):\n return self.search_settings.enable_livesearch\n@@ -35,10 +33,7 @@ def get_types_not_searched(self):\n def set_types_not_searched(self, value):\n self.search_settings.types_not_searched = value\n \n- types_not_searched = property(\n- get_types_not_searched,\n- set_types_not_searched\n- )\n+ types_not_searched = property(get_types_not_searched, set_types_not_searched)\n \n @property\n def sort_on(self):\ndiff --git a/Products/CMFPlone/controlpanel/bbb/security.py b/Products/CMFPlone/controlpanel/bbb/security.py\nindex b1b48f16ae..7450b9a4a9 100644\n--- a/Products/CMFPlone/controlpanel/bbb/security.py\n+++ b/Products/CMFPlone/controlpanel/bbb/security.py\n@@ -10,15 +10,13 @@\n \n @implementer(ISecuritySchema)\n class SecurityControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n self.portal = getSite()\n- self.pmembership = getToolByName(context, \'portal_membership\')\n+ self.pmembership = getToolByName(context, "portal_membership")\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ISecuritySchema, prefix="plone")\n+ self.settings = registry.forInterface(ISecuritySchema, prefix="plone")\n \n def get_enable_self_reg(self):\n return self.settings.enable_self_reg\n@@ -35,8 +33,9 @@ def get_enable_user_pwd_choice(self):\n def set_enable_user_pwd_choice(self, value):\n self.settings.enable_user_pwd_choice = value\n \n- enable_user_pwd_choice = property(get_enable_user_pwd_choice,\n- set_enable_user_pwd_choice)\n+ enable_user_pwd_choice = property(\n+ get_enable_user_pwd_choice, set_enable_user_pwd_choice\n+ )\n \n def get_enable_user_folders(self):\n return self.settings.enable_user_folders\n@@ -45,8 +44,7 @@ def set_enable_user_folders(self, value):\n # additional processing in the event handler\n self.settings.enable_user_folders = value\n \n- enable_user_folders = property(get_enable_user_folders,\n- set_enable_user_folders)\n+ enable_user_folders = property(get_enable_user_folders, set_enable_user_folders)\n \n def get_allow_anon_views_about(self):\n return self.settings.allow_anon_views_about\n@@ -54,8 +52,9 @@ def get_allow_anon_views_about(self):\n def set_allow_anon_views_about(self, value):\n self.settings.allow_anon_views_about = value\n \n- allow_anon_views_about = property(get_allow_anon_views_about,\n- set_allow_anon_views_about)\n+ allow_anon_views_about = property(\n+ get_allow_anon_views_about, set_allow_anon_views_about\n+ )\n \n def get_use_email_as_login(self):\n return self.settings.use_email_as_login\n@@ -64,8 +63,7 @@ def set_use_email_as_login(self, value):\n # additional processing in the event handler\n self.settings.use_email_as_login = value\n \n- use_email_as_login = property(get_use_email_as_login,\n- set_use_email_as_login)\n+ use_email_as_login = property(get_use_email_as_login, set_use_email_as_login)\n \n def get_use_uuid_as_userid(self):\n return self.settings.use_uuid_as_userid\n@@ -73,5 +71,4 @@ def get_use_uuid_as_userid(self):\n def set_use_uuid_as_userid(self, value):\n self.settings.use_uuid_as_userid = value\n \n- use_uuid_as_userid = property(get_use_uuid_as_userid,\n- set_use_uuid_as_userid)\n+ use_uuid_as_userid = property(get_use_uuid_as_userid, set_use_uuid_as_userid)\ndiff --git a/Products/CMFPlone/controlpanel/bbb/site.py b/Products/CMFPlone/controlpanel/bbb/site.py\nindex 73402b154d..c80e918be1 100644\n--- a/Products/CMFPlone/controlpanel/bbb/site.py\n+++ b/Products/CMFPlone/controlpanel/bbb/site.py\n@@ -9,7 +9,6 @@\n \n @implementer(ISiteSchema)\n class SiteControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n@@ -31,6 +30,6 @@ def set_webstats_js(self, value):\n site_title = property(get_site_title, set_site_title)\n webstats_js = property(get_webstats_js, set_webstats_js)\n \n- site_logo = FieldProperty(ISiteSchema[\'site_logo\'])\n- enable_sitemap = FieldProperty(ISiteSchema[\'enable_sitemap\'])\n- exposeDCMetaTags = FieldProperty(ISiteSchema[\'exposeDCMetaTags\'])\n+ site_logo = FieldProperty(ISiteSchema["site_logo"])\n+ enable_sitemap = FieldProperty(ISiteSchema["enable_sitemap"])\n+ exposeDCMetaTags = FieldProperty(ISiteSchema["exposeDCMetaTags"])\ndiff --git a/Products/CMFPlone/controlpanel/bbb/usergroups.py b/Products/CMFPlone/controlpanel/bbb/usergroups.py\nindex 0c819c7136..4330421011 100644\n--- a/Products/CMFPlone/controlpanel/bbb/usergroups.py\n+++ b/Products/CMFPlone/controlpanel/bbb/usergroups.py\n@@ -9,7 +9,6 @@\n \n @implementer(IUserGroupsSettingsSchema)\n class UserGroupsSettingsControlPanelAdapter:\n-\n adapts(IPloneSiteRoot)\n \n def __init__(self, context):\n@@ -17,7 +16,8 @@ def __init__(self, context):\n self.portal = getSite()\n registry = getUtility(IRegistry)\n self.usergroups_settings = registry.forInterface(\n- IUserGroupsSettingsSchema, prefix="plone")\n+ IUserGroupsSettingsSchema, prefix="plone"\n+ )\n \n def get_many_groups(self):\n return self.usergroups_settings.many_groups\ndiff --git a/Products/CMFPlone/controlpanel/browser/actions.py b/Products/CMFPlone/controlpanel/browser/actions.py\nindex ced92e851c..9c361e6462 100644\n--- a/Products/CMFPlone/controlpanel/browser/actions.py\n+++ b/Products/CMFPlone/controlpanel/browser/actions.py\n@@ -26,50 +26,52 @@ class ActionListControlPanel(BrowserView):\n def __init__(self, context, request):\n self.context = context\n self.request = request\n- self.portal_actions = getToolByName(self.context, \'portal_actions\')\n+ self.portal_actions = getToolByName(self.context, "portal_actions")\n \n def display(self):\n actions = []\n for category in self.portal_actions.objectValues():\n- if category.id == \'controlpanel\':\n+ if category.id == "controlpanel":\n continue\n if not IActionCategory.providedBy(category):\n continue\n cat_infos = {\n- \'id\': category.id,\n- \'title\': category.title or category.id,\n+ "id": category.id,\n+ "title": category.title or category.id,\n }\n action_list = []\n for action in category.objectValues():\n if IAction.providedBy(action):\n- action_list.append({\n- \'id\': action.id,\n- \'title\': action.title,\n- \'url\': action.absolute_url(),\n- \'visible\': action.visible,\n- })\n- cat_infos[\'actions\'] = action_list\n+ action_list.append(\n+ {\n+ "id": action.id,\n+ "title": action.title,\n+ "url": action.absolute_url(),\n+ "visible": action.visible,\n+ }\n+ )\n+ cat_infos["actions"] = action_list\n actions.append(cat_infos)\n \n self.actions = actions\n return self.template()\n \n def __call__(self):\n- if self.request.get(\'delete\'):\n- action_id = self.request[\'actionid\']\n- category = self.portal_actions[self.request[\'category\']]\n+ if self.request.get("delete"):\n+ action_id = self.request["actionid"]\n+ category = self.portal_actions[self.request["category"]]\n category.manage_delObjects([action_id])\n- self.request.RESPONSE.redirect(\'@@actions-controlpanel\')\n- if self.request.get(\'hide\'):\n- action_id = self.request[\'actionid\']\n- category = self.portal_actions[self.request[\'category\']]\n+ self.request.RESPONSE.redirect("@@actions-controlpanel")\n+ if self.request.get("hide"):\n+ action_id = self.request["actionid"]\n+ category = self.portal_actions[self.request["category"]]\n category[action_id].visible = False\n- self.request.RESPONSE.redirect(\'@@actions-controlpanel\')\n- if self.request.get(\'show\'):\n- action_id = self.request[\'actionid\']\n- category = self.portal_actions[self.request[\'category\']]\n+ self.request.RESPONSE.redirect("@@actions-controlpanel")\n+ if self.request.get("show"):\n+ action_id = self.request["actionid"]\n+ category = self.portal_actions[self.request["category"]]\n category[action_id].visible = True\n- self.request.RESPONSE.redirect(\'@@actions-controlpanel\')\n+ self.request.RESPONSE.redirect("@@actions-controlpanel")\n return self.display()\n \n \n@@ -87,7 +89,7 @@ def get_category(self):\n return self.current_category.id\n \n def set_category(self, value):\n- portal_actions = getToolByName(self.context, \'portal_actions\')\n+ portal_actions = getToolByName(self.context, "portal_actions")\n new_category = portal_actions.get(value)\n cookie = self.current_category.manage_cutObjects(ids=[self.context.id])\n new_category.manage_pasteObjects(cookie)\n@@ -98,7 +100,7 @@ def get_title(self):\n return self.context.title\n \n def set_title(self, value):\n- self.context._setPropValue(\'title\', value)\n+ self.context._setPropValue("title", value)\n \n title = property(get_title, set_title)\n \n@@ -106,7 +108,7 @@ def get_description(self):\n return self.context.description\n \n def set_description(self, value):\n- self.context._setPropValue(\'description\', value)\n+ self.context._setPropValue("description", value)\n \n description = property(get_description, set_description)\n \n@@ -114,7 +116,7 @@ def get_i18n_domain(self):\n return self.context.i18n_domain\n \n def set_i18n_domain(self, value):\n- self.context._setPropValue(\'i18n_domain\', value)\n+ self.context._setPropValue("i18n_domain", value)\n \n i18n_domain = property(get_i18n_domain, set_i18n_domain)\n \n@@ -122,7 +124,7 @@ def get_url_expr(self):\n return self.context.url_expr\n \n def set_url_expr(self, value):\n- self.context._setPropValue(\'url_expr\', value)\n+ self.context._setPropValue("url_expr", value)\n \n url_expr = property(get_url_expr, set_url_expr)\n \n@@ -130,7 +132,7 @@ def get_available_expr(self):\n return self.context.available_expr\n \n def set_available_expr(self, value):\n- self.context._setPropValue(\'available_expr\', value)\n+ self.context._setPropValue("available_expr", value)\n \n available_expr = property(get_available_expr, set_available_expr)\n \n@@ -138,7 +140,7 @@ def get_permissions(self):\n return self.context.permissions\n \n def set_permissions(self, value):\n- self.context._setPropValue(\'permissions\', value)\n+ self.context._setPropValue("permissions", value)\n \n permissions = property(get_permissions, set_permissions)\n \n@@ -146,7 +148,7 @@ def get_visible(self):\n return self.context.visible\n \n def set_visible(self, value):\n- self.context._setPropValue(\'visible\', value)\n+ self.context._setPropValue("visible", value)\n \n visible = property(get_visible, set_visible)\n \n@@ -155,13 +157,13 @@ def get_position(self):\n return position + 1\n \n def set_position(self, value):\n- current_position = self.current_category.objectIds().index(\n- self.context.id)\n+ current_position = self.current_category.objectIds().index(self.context.id)\n all_actions = list(self.current_category._objects)\n current_action = all_actions.pop(current_position)\n new_position = value - 1\n- all_actions = all_actions[0:new_position] + [current_action] + \\\n- all_actions[new_position:]\n+ all_actions = (\n+ all_actions[0:new_position] + [current_action] + all_actions[new_position:]\n+ )\n self.current_category._objects = tuple(all_actions)\n \n position = property(get_position, set_position)\n@@ -176,9 +178,9 @@ def set_modal(self, value):\n # We cannot define a property when an attribute with the same\n # name already exists.\n delattr(self.context, "modal")\n- self.context._setProperty(\'modal\', value, \'string\')\n+ self.context._setProperty("modal", value, "string")\n else:\n- self.context._setPropValue(\'modal\', value)\n+ self.context._setPropValue("modal", value)\n \n modal = property(get_modal, set_modal)\n \n@@ -188,7 +190,7 @@ class ActionControlPanel(AutoExtensibleForm, form.EditForm):\n \n schema = IActionSchema\n ignoreContext = False\n- label = _(\'Action Settings\')\n+ label = _("Action Settings")\n \n \n class NewActionControlPanel(AutoExtensibleForm, form.AddForm):\n@@ -196,17 +198,17 @@ class NewActionControlPanel(AutoExtensibleForm, form.AddForm):\n \n schema = INewActionSchema\n ignoreContext = True\n- label = _(\'New action\')\n+ label = _("New action")\n \n def createAndAdd(self, data):\n- portal_actions = getToolByName(self.context, \'portal_actions\')\n- category = portal_actions.get(data[\'category\'])\n- action_id = data[\'id\']\n+ portal_actions = getToolByName(self.context, "portal_actions")\n+ category = portal_actions.get(data["category"])\n+ action_id = data["id"]\n action = Action(\n action_id,\n title=action_id,\n- i18n_domain=\'plone\',\n- permissions=[\'View\'],\n+ i18n_domain="plone",\n+ permissions=["View"],\n )\n category[action_id] = action\n notify(ObjectCreatedEvent(action))\ndiff --git a/Products/CMFPlone/controlpanel/browser/dateandtime.py b/Products/CMFPlone/controlpanel/browser/dateandtime.py\nindex d9d606e825..9683308fb1 100644\n--- a/Products/CMFPlone/controlpanel/browser/dateandtime.py\n+++ b/Products/CMFPlone/controlpanel/browser/dateandtime.py\n@@ -5,7 +5,6 @@\n \n \n class DateAndTimeControlPanelForm(RegistryEditForm):\n-\n id = "DateAndTimeControlPanel"\n schema = IDateAndTimeSchema\n schema_prefix = "plone"\n@@ -13,7 +12,7 @@ class DateAndTimeControlPanelForm(RegistryEditForm):\n label = _("label_dateandtime_settings", default="Date and Time Settings")\n description = _(\n "help_event_settings",\n- default="Date and Time related settings like timezone(s), etc."\n+ default="Date and Time related settings like timezone(s), etc.",\n )\n \n \ndiff --git a/Products/CMFPlone/controlpanel/browser/editing.py b/Products/CMFPlone/controlpanel/browser/editing.py\nindex 3c48883959..8778eaef65 100644\n--- a/Products/CMFPlone/controlpanel/browser/editing.py\n+++ b/Products/CMFPlone/controlpanel/browser/editing.py\n@@ -5,7 +5,6 @@\n \n \n class EditingControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "EditingControlPanel"\n label = _("Editing Settings")\n schema = IEditingSchema\n@@ -14,7 +13,7 @@ class EditingControlPanelForm(controlpanel.RegistryEditForm):\n def updateWidgets(self):\n super().updateWidgets()\n # hide the available_editors field/widgets\n- self.widgets[\'available_editors\'].mode = interfaces.HIDDEN_MODE\n+ self.widgets["available_editors"].mode = interfaces.HIDDEN_MODE\n \n \n class EditingControlPanel(controlpanel.ControlPanelFormWrapper):\ndiff --git a/Products/CMFPlone/controlpanel/browser/error_log_form.py b/Products/CMFPlone/controlpanel/browser/error_log_form.py\nindex 7bd67ac821..b91169ff4c 100644\n--- a/Products/CMFPlone/controlpanel/browser/error_log_form.py\n+++ b/Products/CMFPlone/controlpanel/browser/error_log_form.py\n@@ -7,41 +7,53 @@\n \n \n class ErrorLogUpdate(BrowserView):\n-\n def __call__(self):\n member = api.user.get_current()\n \n- if getattr(self.request, \'form.button.search\', None) is not None:\n- search = self.request.form.get(\'search_entry\')\n- if search == \'\':\n+ if getattr(self.request, "form.button.search", None) is not None:\n+ search = self.request.form.get("search_entry")\n+ if search == "":\n member.setProperties(error_log_update=0.0)\n- self.context.plone_utils.addPortalMessage(_(\'Showing all entries\'))\n- return self.request.RESPONSE.redirect(self.context.absolute_url() + \'/@@error-log-form\')\n- return self.request.RESPONSE.redirect(self.context.absolute_url() + \'/@@error-log-show-entry?id=%s\' % search)\n-\n- elif getattr(self.request, \'form.button.showall\', None) is not None:\n+ self.context.plone_utils.addPortalMessage(_("Showing all entries"))\n+ return self.request.RESPONSE.redirect(\n+ self.context.absolute_url() + "/@@error-log-form"\n+ )\n+ return self.request.RESPONSE.redirect(\n+ self.context.absolute_url() + "/@@error-log-show-entry?id=%s" % search\n+ )\n+\n+ elif getattr(self.request, "form.button.showall", None) is not None:\n member.setProperties(error_log_update=0.0)\n- self.context.plone_utils.addPortalMessage(_(\'Showing all entries\'))\n- return self.request.RESPONSE.redirect(self.context.absolute_url() + \'/@@error-log-form\')\n+ self.context.plone_utils.addPortalMessage(_("Showing all entries"))\n+ return self.request.RESPONSE.redirect(\n+ self.context.absolute_url() + "/@@error-log-form"\n+ )\n \n- elif getattr(self.request, \'form.button.clear\', None) is not None:\n+ elif getattr(self.request, "form.button.clear", None) is not None:\n member.setProperties(error_log_update=DateTime().timeTime())\n- self.context.plone_utils.addPortalMessage(_(\'Entries cleared\'))\n- return self.request.RESPONSE.redirect(self.context.absolute_url() + \'/@@error-log-form\')\n+ self.context.plone_utils.addPortalMessage(_("Entries cleared"))\n+ return self.request.RESPONSE.redirect(\n+ self.context.absolute_url() + "/@@error-log-form"\n+ )\n \n else:\n- return self.request.RESPONSE.redirect(self.context.absolute_url() + \'/@@error-log-form\')\n+ return self.request.RESPONSE.redirect(\n+ self.context.absolute_url() + "/@@error-log-form"\n+ )\n \n \n class ErrorLogSetProperties(BrowserView):\n-\n def __call__(self):\n- keep_entries = self.request.form.get(\'keep_entries\')\n- ignored_exceptions = self.request.form.get(\'ignored_exceptions\')\n- copy_to_zlog = self.request.form.get(\'copy_to_zlog\', 0)\n+ keep_entries = self.request.form.get("keep_entries")\n+ ignored_exceptions = self.request.form.get("ignored_exceptions")\n+ copy_to_zlog = self.request.form.get("copy_to_zlog", 0)\n \n ignored_exceptions = map(safe_nativestring, ignored_exceptions)\n- self.context.error_log.setProperties(keep_entries, copy_to_zlog, ignored_exceptions)\n- self.context.plone_utils.addPortalMessage(_(\'Changes made.\'))\n-\n- return self.request.RESPONSE.redirect(self.context.absolute_url() + \'/@@error-log-form\')\n+ self.context.error_log.setProperties(\n+ keep_entries, copy_to_zlog, ignored_exceptions\n+ )\n+ self.context.plone_utils.addPortalMessage(_("Changes made."))\n+\n+ return self.request.RESPONSE.redirect(\n+ self.context.absolute_url() + "/@@error-log-form"\n+ )\ndiff --git a/Products/CMFPlone/controlpanel/browser/filter.py b/Products/CMFPlone/controlpanel/browser/filter.py\nindex 09a3e8209f..d9210e96f3 100644\n--- a/Products/CMFPlone/controlpanel/browser/filter.py\n+++ b/Products/CMFPlone/controlpanel/browser/filter.py\n@@ -10,14 +10,15 @@\n class FilterControlPanel(controlpanel.RegistryEditForm):\n id = "FilterControlPanel"\n label = _("HTML Filtering Settings")\n- description = _("Keep in mind that editors like TinyMCE might have "\n- "additional filters.")\n+ description = _(\n+ "Keep in mind that editors like TinyMCE might have " "additional filters."\n+ )\n schema = IFilterSchema\n schema_prefix = "plone"\n form_name = _("HTML Filtering Settings")\n control_panel_view = "filter-controlpanel"\n \n- @button.buttonAndHandler(_("Save"), name=\'save\')\n+ @button.buttonAndHandler(_("Save"), name="save")\n def handleSave(self, action): # NOQA\n data, errors = self.extractData()\n if errors:\n@@ -25,32 +26,31 @@ def handleSave(self, action): # NOQA\n return\n \n self.applyChanges(data)\n+ IStatusMessage(self.request).addStatusMessage(_("Changes saved."), "info")\n IStatusMessage(self.request).addStatusMessage(\n- _("Changes saved."),\n- "info")\n- IStatusMessage(self.request).addStatusMessage(\n- _("HTML generation is heavily cached across Plone. You may "\n- "have to edit existing content or restart your server to see "\n- "the changes."),\n- "warning")\n+ _(\n+ "HTML generation is heavily cached across Plone. You may "\n+ "have to edit existing content or restart your server to see "\n+ "the changes."\n+ ),\n+ "warning",\n+ )\n self.request.response.redirect(self.request.getURL())\n \n- @button.buttonAndHandler(_("Cancel"), name=\'cancel\')\n+ @button.buttonAndHandler(_("Cancel"), name="cancel")\n def handleCancel(self, action):\n- IStatusMessage(self.request).addStatusMessage(\n- _("Changes canceled."),\n- "info")\n- self.request.response.redirect("{}/{}".format(\n- self.context.absolute_url(),\n- self.control_panel_view))\n+ IStatusMessage(self.request).addStatusMessage(_("Changes canceled."), "info")\n+ self.request.response.redirect(\n+ "{}/{}".format(self.context.absolute_url(), self.control_panel_view)\n+ )\n \n \n class ControlPanelFormWrapper(layout.FormWrapper):\n """Use this form as the plone.z3cform layout wrapper to get the control\n panel layout.\n """\n- index = ViewPageTemplateFile(\'filter_controlpanel.pt\')\n+\n+ index = ViewPageTemplateFile("filter_controlpanel.pt")\n \n \n-FilterControlPanelView = layout.wrap_form(\n- FilterControlPanel, ControlPanelFormWrapper)\n+FilterControlPanelView = layout.wrap_form(FilterControlPanel, ControlPanelFormWrapper)\ndiff --git a/Products/CMFPlone/controlpanel/browser/imaging.py b/Products/CMFPlone/controlpanel/browser/imaging.py\nindex a5cb3e943c..be12bb0345 100644\n--- a/Products/CMFPlone/controlpanel/browser/imaging.py\n+++ b/Products/CMFPlone/controlpanel/browser/imaging.py\n@@ -4,11 +4,10 @@\n from plone.base.interfaces.controlpanel import IImagingSchema\n \n \n-log = getLogger(\'Plone\')\n+log = getLogger("Plone")\n \n \n class ImagingControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "ImagingSettings"\n label = _("Image Handling Settings")\n schema = IImagingSchema\ndiff --git a/Products/CMFPlone/controlpanel/browser/language.py b/Products/CMFPlone/controlpanel/browser/language.py\nindex 289715aa02..fa9b12ff68 100644\n--- a/Products/CMFPlone/controlpanel/browser/language.py\n+++ b/Products/CMFPlone/controlpanel/browser/language.py\n@@ -6,47 +6,46 @@\n \n \n class LanguageControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "LanguageControlPanel"\n label = _("heading_language_settings", default="Language Settings")\n- description = _("description_language_settings",\n- default="Settings related to interface languages and "\n- "content translations.")\n+ description = _(\n+ "description_language_settings",\n+ default="Settings related to interface languages and " "content translations.",\n+ )\n \n schema = ILanguageSchema\n schema_prefix = "plone"\n \n- @button.buttonAndHandler(_("Save"), name=\'save\')\n+ @button.buttonAndHandler(_("Save"), name="save")\n def handleSave(self, action):\n data, errors = self.extractData()\n if errors:\n self.status = self.formErrorsMessage\n return\n # We need to check if the default language is in available languages\n- if \'default_language\' in data and \'available_languages\' in data and \\\n- data[\'default_language\'] not in data[\'available_languages\']:\n+ if (\n+ "default_language" in data\n+ and "available_languages" in data\n+ and data["default_language"] not in data["available_languages"]\n+ ):\n IStatusMessage(self.request).addStatusMessage(\n- _("Default language not in available languages"),\n- "error")\n+ _("Default language not in available languages"), "error"\n+ )\n \n # e = Invalid(_(u"Default language not in available languages"))\n # raise WidgetActionExecutionError(\'default_language\', e)\n return\n \n self.applyChanges(data)\n- IStatusMessage(self.request).addStatusMessage(\n- _("Changes saved."),\n- "info")\n+ IStatusMessage(self.request).addStatusMessage(_("Changes saved."), "info")\n self.request.response.redirect(self.request.getURL())\n \n- @button.buttonAndHandler(_("Cancel"), name=\'cancel\')\n+ @button.buttonAndHandler(_("Cancel"), name="cancel")\n def handleCancel(self, action):\n- IStatusMessage(self.request).addStatusMessage(\n- _("Changes canceled."),\n- "info")\n- self.request.response.redirect("{}/{}".format(\n- self.context.absolute_url(),\n- self.control_panel_view))\n+ IStatusMessage(self.request).addStatusMessage(_("Changes canceled."), "info")\n+ self.request.response.redirect(\n+ "{}/{}".format(self.context.absolute_url(), self.control_panel_view)\n+ )\n \n \n class LanguageControlPanel(controlpanel.ControlPanelFormWrapper):\ndiff --git a/Products/CMFPlone/controlpanel/browser/mail.py b/Products/CMFPlone/controlpanel/browser/mail.py\nindex 4bb7c97ff2..caf29a899a 100644\n--- a/Products/CMFPlone/controlpanel/browser/mail.py\n+++ b/Products/CMFPlone/controlpanel/browser/mail.py\n@@ -14,21 +14,20 @@\n import sys\n \n \n-log = getLogger(\'Plone\')\n+log = getLogger("Plone")\n \n \n class MailControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "MailControlPanel"\n label = _("Mail Settings")\n schema = IMailSchema\n schema_prefix = "plone"\n \n- @button.buttonAndHandler(_(\'Save\'), name=None)\n+ @button.buttonAndHandler(_("Save"), name=None)\n def handleSave(self, action):\n self.save()\n \n- @button.buttonAndHandler(_(\'Cancel\'), name=\'cancel\')\n+ @button.buttonAndHandler(_("Cancel"), name="cancel")\n def handleCancel(self, action):\n super().handleCancel(self, action)\n \n@@ -38,34 +37,36 @@ def save(self):\n self.status = self.formErrorsMessage\n return False\n # keep password field\n- smtp_user_id = (data.get(\'smtp_userid\') or \'\').strip()\n- smtp_pass = (data.get(\'smtp_pass\') or \'\').strip()\n+ smtp_user_id = (data.get("smtp_userid") or "").strip()\n+ smtp_pass = (data.get("smtp_pass") or "").strip()\n if smtp_user_id and not smtp_pass:\n- del data[\'smtp_pass\']\n+ del data["smtp_pass"]\n \n self.applyChanges(data)\n return True\n \n @button.buttonAndHandler(\n- _(\'label_smtp_test\', default=\'Save and send test e-mail\'),\n- name=\'test\')\n+ _("label_smtp_test", default="Save and send test e-mail"), name="test"\n+ )\n def handle_test_action(self, action):\n # Save data first\n if not self.save():\n return\n- mailhost = getToolByName(self.context, \'MailHost\')\n+ mailhost = getToolByName(self.context, "MailHost")\n \n registry = getUtility(IRegistry)\n- mail_settings = registry.forInterface(IMailSchema, prefix=\'plone\')\n+ mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n fromaddr = mail_settings.email_from_address\n \n- message = ("Hi,\\n\\nThis is a test message sent from the Plone "\n- "\'Mail settings\' control panel. Your receipt of this "\n- "message (at the address specified in the Site \'From\' "\n- "address field) indicates that your e-mail server is "\n- "working!\\n\\n"\n- "Have a nice day.\\n\\n"\n- "Love,\\n\\nPlone")\n+ message = (\n+ "Hi,\\n\\nThis is a test message sent from the Plone "\n+ "\'Mail settings\' control panel. Your receipt of this "\n+ "message (at the address specified in the Site \'From\' "\n+ "address field) indicates that your e-mail server is "\n+ "working!\\n\\n"\n+ "Have a nice day.\\n\\n"\n+ "Love,\\n\\nPlone"\n+ )\n email_charset = mail_settings.email_charset\n subject = "Test e-mail from Plone"\n \n@@ -77,25 +78,28 @@ def handle_test_action(self, action):\n try:\n socket.setdefaulttimeout(3)\n try:\n- mailhost.send(message,\n- mto=fromaddr,\n- mfrom=fromaddr,\n- subject=subject,\n- charset=email_charset,\n- immediate=True)\n+ mailhost.send(\n+ message,\n+ mto=fromaddr,\n+ mfrom=fromaddr,\n+ subject=subject,\n+ charset=email_charset,\n+ immediate=True,\n+ )\n \n except (OSError, MailHostError, smtplib.SMTPException):\n # Connection refused or timeout.\n- log.exception(\'Unable to send test e-mail.\')\n+ log.exception("Unable to send test e-mail.")\n value = sys.exc_info()[1]\n- msg = _(\'Unable to send test e-mail ${error}.\',\n- mapping={\'error\': str(value)})\n- IStatusMessage(self.request).addStatusMessage(\n- msg, type=\'error\')\n+ msg = _(\n+ "Unable to send test e-mail ${error}.",\n+ mapping={"error": str(value)},\n+ )\n+ IStatusMessage(self.request).addStatusMessage(msg, type="error")\n else:\n IStatusMessage(self.request).addStatusMessage(\n- _(\'Success! Check your mailbox for the test message.\'),\n- type=\'info\')\n+ _("Success! Check your mailbox for the test message."), type="info"\n+ )\n finally:\n # Restore timeout to default value\n socket.setdefaulttimeout(timeout)\ndiff --git a/Products/CMFPlone/controlpanel/browser/maintenance.py b/Products/CMFPlone/controlpanel/browser/maintenance.py\nindex c9baf3b9d3..f429f3cbae 100644\n--- a/Products/CMFPlone/controlpanel/browser/maintenance.py\n+++ b/Products/CMFPlone/controlpanel/browser/maintenance.py\n@@ -38,20 +38,20 @@ class MaintenanceControlPanel(AutoExtensibleForm, form.EditForm):\n \n schema = IMaintenanceSchema\n id = "maintenance-control-panel"\n- label = _(\'Maintenance Settings\')\n+ label = _("Maintenance Settings")\n description = _("Zope server and site maintenance options.")\n- form_name = _(\'Zope Database Packing\')\n+ form_name = _("Zope Database Packing")\n control_panel_view = "maintenance-controlpanel"\n- template = ViewPageTemplateFile(\'maintenance.pt\')\n+ template = ViewPageTemplateFile("maintenance.pt")\n \n @memoize\n def portal(self):\n portal_state = getMultiAdapter(\n- (aq_inner(self.context), self.request),\n- name=\'plone_portal_state\')\n+ (aq_inner(self.context), self.request), name="plone_portal_state"\n+ )\n return portal_state.portal()\n \n- @button.buttonAndHandler(_(\'Pack database now\'), name=\'pack\')\n+ @button.buttonAndHandler(_("Pack database now"), name="pack")\n def handle_pack_action(self, action):\n data, errors = self.extractData()\n if errors:\n@@ -60,69 +60,71 @@ def handle_pack_action(self, action):\n CheckAuthenticator(self.request)\n if not self.available():\n self.status = _(\n- \'text_not_allowed_manage_server\',\n- default=\'You are not allowed to manage the Zope server.\'\n+ "text_not_allowed_manage_server",\n+ default="You are not allowed to manage the Zope server.",\n )\n return\n \n- days = data.get(\'days\', None)\n+ days = data.get("days", None)\n # skip the actual pack method in tests\n if days is not None and isinstance(days, int) and days >= 0:\n db = self.portal()._p_jar.db()\n t = time.time() - (days * 86400)\n db.pack(t)\n- self.status = _(\'Packed the database.\')\n+ self.status = _("Packed the database.")\n \n- @button.buttonAndHandler(_(\'Shut down\'), name=\'shutdown\')\n+ @button.buttonAndHandler(_("Shut down"), name="shutdown")\n def handle_shutdown_action(self, action):\n CheckAuthenticator(self.request)\n if not self.available():\n self.status = _(\n- \'text_not_allowed_manage_server\',\n- default=\'You are not allowed to manage the Zope server.\'\n+ "text_not_allowed_manage_server",\n+ default="You are not allowed to manage the Zope server.",\n )\n return\n try:\n user = \'"%s"\' % getSecurityManager().getUser().getUserName()\n except:\n- user = \'unknown user\'\n+ user = "unknown user"\n logger.info("Shutdown requested by %s" % user)\n if LIFETIME:\n shutdown(0)\n else:\n raise\n # TODO: returning html has no effect in button handlers\n- self.request.response.setHeader(\'X-Theme-Disabled\', \'True\')\n+ self.request.response.setHeader("X-Theme-Disabled", "True")\n return """{}""".format(\n- _(\'plone_shutdown\', default="Zope is shutting down.")\n+ _("plone_shutdown", default="Zope is shutting down.")\n )\n \n- @button.buttonAndHandler(_(\'Restart\'), name=\'restart\')\n+ @button.buttonAndHandler(_("Restart"), name="restart")\n def handle_restart_action(self, action):\n CheckAuthenticator(self.request)\n if not self.available():\n self.status = _(\n- \'text_not_allowed_manage_server\',\n- default=\'You are not allowed to manage the Zope server.\'\n+ "text_not_allowed_manage_server",\n+ default="You are not allowed to manage the Zope server.",\n )\n return\n \n try:\n user = \'"%s"\' % getSecurityManager().getUser().getUserName()\n except:\n- user = \'unknown user\'\n+ user = "unknown user"\n logger.info("Restart requested by %s" % user)\n shutdown(1)\n- url = self.request.get(\'URL\')\n+ url = self.request.get("URL")\n # TODO: returning html has no effect in button handlers\n- self.request.response.setHeader(\'X-Theme-Disabled\', \'True\')\n+ self.request.response.setHeader("X-Theme-Disabled", "True")\n return """\n \n {}""".format(\n escape(url, 1),\n- _(\'plone_restarting\',\n+ _(\n+ "plone_restarting",\n default="Zope is restarting. This page will refresh in 30"\n- " seconds...")\n+ " seconds...",\n+ ),\n )\n \n def available(self):\n@@ -131,7 +133,7 @@ def available(self):\n return sm.checkPermission(view_management_screens, root)\n \n def isRestartable(self):\n- if \'ZMANAGED\' in os.environ:\n+ if "ZMANAGED" in os.environ:\n return True\n return False\n \n@@ -139,9 +141,9 @@ def isDevelopmentMode(self):\n return bool(getConfiguration().debug_mode)\n \n def coreVersions(self):\n- mt = getToolByName(self.context, \'portal_migration\')\n+ mt = getToolByName(self.context, "portal_migration")\n versions = mt.coreVersions()\n- versions[\'Instance\'] = versions[\'Plone Instance\']\n+ versions["Instance"] = versions["Plone Instance"]\n return versions\n \n def dbName(self):\n@@ -155,5 +157,5 @@ def dbSize(self):\n return size\n \n if size >= 1048576.0:\n- return \'%.1f MB\' % (size / 1048576.0)\n- return \'%.1f kB\' % (size / 1024.0)\n+ return "%.1f MB" % (size / 1048576.0)\n+ return "%.1f kB" % (size / 1024.0)\ndiff --git a/Products/CMFPlone/controlpanel/browser/markup.py b/Products/CMFPlone/controlpanel/browser/markup.py\nindex e6e7949401..e628160e78 100644\n--- a/Products/CMFPlone/controlpanel/browser/markup.py\n+++ b/Products/CMFPlone/controlpanel/browser/markup.py\n@@ -5,7 +5,6 @@\n \n \n class MarkupControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "MarkupControlPanel"\n label = _("Markup Settings")\n schema = IMarkupSchema\n@@ -13,8 +12,7 @@ class MarkupControlPanelForm(controlpanel.RegistryEditForm):\n \n def updateFields(self):\n super().updateFields()\n- self.fields[\'allowed_types\'].widgetFactory = \\\n- CheckBoxFieldWidget\n+ self.fields["allowed_types"].widgetFactory = CheckBoxFieldWidget\n \n \n class MarkupControlPanel(controlpanel.ControlPanelFormWrapper):\ndiff --git a/Products/CMFPlone/controlpanel/browser/navigation.py b/Products/CMFPlone/controlpanel/browser/navigation.py\nindex e005fc6771..ab0a59e0a2 100644\n--- a/Products/CMFPlone/controlpanel/browser/navigation.py\n+++ b/Products/CMFPlone/controlpanel/browser/navigation.py\n@@ -5,24 +5,22 @@\n \n \n class NavigationControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "NavigationControlPanel"\n label = _("Navigation Settings")\n description = _(\n- "Lets you control how navigation is constructed in your site. " +\n- "Note that to control how the navigation tree is displayed, you " +\n- "should go to \'Manage portlets\' at the root of the site (or " +\n- "wherever a navigation tree portlet has been added) and change " +\n- "its settings directly.")\n+ "Lets you control how navigation is constructed in your site. "\n+ + "Note that to control how the navigation tree is displayed, you "\n+ + "should go to \'Manage portlets\' at the root of the site (or "\n+ + "wherever a navigation tree portlet has been added) and change "\n+ + "its settings directly."\n+ )\n schema = INavigationSchema\n schema_prefix = "plone"\n \n def updateFields(self):\n super().updateFields()\n- self.fields[\'displayed_types\'].widgetFactory = \\\n- CheckBoxFieldWidget\n- self.fields[\'workflow_states_to_show\'].widgetFactory = \\\n- CheckBoxFieldWidget\n+ self.fields["displayed_types"].widgetFactory = CheckBoxFieldWidget\n+ self.fields["workflow_states_to_show"].widgetFactory = CheckBoxFieldWidget\n \n \n class NavigationControlPanel(controlpanel.ControlPanelFormWrapper):\ndiff --git a/Products/CMFPlone/controlpanel/browser/overview.py b/Products/CMFPlone/controlpanel/browser/overview.py\nindex ab5be04ade..e0c68ece71 100644\n--- a/Products/CMFPlone/controlpanel/browser/overview.py\n+++ b/Products/CMFPlone/controlpanel/browser/overview.py\n@@ -25,7 +25,6 @@\n \n \n class OverviewControlPanel(controlpanel.RegistryEditForm):\n-\n template = ViewPageTemplateFile("overview.pt")\n \n base_category = "controlpanel"\n@@ -76,7 +75,6 @@ def server_info(self):\n }\n \n def version_overview(self):\n-\n core_versions = self.core_versions()\n versions = [\n "Plone {} ({})".format(\ndiff --git a/Products/CMFPlone/controlpanel/browser/prefsmaintemplate.py b/Products/CMFPlone/controlpanel/browser/prefsmaintemplate.py\nindex 5423716bc0..2699b7752a 100644\n--- a/Products/CMFPlone/controlpanel/browser/prefsmaintemplate.py\n+++ b/Products/CMFPlone/controlpanel/browser/prefsmaintemplate.py\n@@ -3,8 +3,7 @@\n \n \n class PrefsMainTemplate(BrowserView):\n-\n- prefs_main_template_name = \'prefsmaintemplate.pt\'\n+ prefs_main_template_name = "prefsmaintemplate.pt"\n \n def __call__(self):\n return ViewPageTemplateFile(self.prefs_main_template_name)\ndiff --git a/Products/CMFPlone/controlpanel/browser/quickinstaller.py b/Products/CMFPlone/controlpanel/browser/quickinstaller.py\nindex 6e59ecbe9a..37733f302e 100644\n--- a/Products/CMFPlone/controlpanel/browser/quickinstaller.py\n+++ b/Products/CMFPlone/controlpanel/browser/quickinstaller.py\n@@ -14,16 +14,15 @@\n import transaction\n \n \n-logger = logging.getLogger(\'Plone\')\n+logger = logging.getLogger("Plone")\n \n \n class InstallerView(BrowserView):\n- """View on all contexts for installing and uninstalling products.\n- """\n+ """View on all contexts for installing and uninstalling products."""\n \n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n- self.ps = getToolByName(self.context, \'portal_setup\')\n+ self.ps = getToolByName(self.context, "portal_setup")\n self.errors = {}\n \n def is_profile_installed(self, profile_id):\n@@ -33,19 +32,20 @@ def is_product_installed(self, product_id):\n profile = self.get_install_profile(product_id, allow_hidden=True)\n if not profile:\n return False\n- return self.is_profile_installed(profile[\'id\'])\n+ return self.is_profile_installed(profile["id"])\n \n def _install_profile_info(self, product_id):\n- """List extension profile infos of a given product.\n- """\n+ """List extension profile infos of a given product."""\n profiles = self.ps.listProfileInfo()\n # We are only interested in extension profiles for the product.\n # TODO Remove the manual Products.* check here. It is still needed.\n profiles = [\n- prof for prof in profiles\n- if prof[\'type\'] == EXTENSION and (\n- prof[\'product\'] == product_id or\n- prof[\'product\'] == \'Products.%s\' % product_id\n+ prof\n+ for prof in profiles\n+ if prof["type"] == EXTENSION\n+ and (\n+ prof["product"] == product_id\n+ or prof["product"] == "Products.%s" % product_id\n )\n ]\n return profiles\n@@ -55,7 +55,7 @@ def get_install_profiles(self, product_id):\n \n TODO Might be superfluous.\n """\n- return [prof[\'id\'] for prof in self._install_profile_info(product_id)]\n+ return [prof["id"] for prof in self._install_profile_info(product_id)]\n \n def _get_profile(self, product_id, name, strict=True, allow_hidden=False):\n """Return profile with given name.\n@@ -83,7 +83,7 @@ def _get_profile(self, product_id, name, strict=True, allow_hidden=False):\n utils = getAllUtilitiesRegisteredFor(INonInstallable)\n hidden = []\n for util in utils:\n- gnip = getattr(util, \'getNonInstallableProfiles\', None)\n+ gnip = getattr(util, "getNonInstallableProfiles", None)\n if gnip is None:\n continue\n hidden.extend(gnip())\n@@ -93,8 +93,8 @@ def _get_profile(self, product_id, name, strict=True, allow_hidden=False):\n prime_candidates = []\n hidden_candidates = []\n for profile in profiles:\n- profile_id = profile[\'id\']\n- profile_id_parts = profile_id.split(\':\')\n+ profile_id = profile["id"]\n+ profile_id_parts = profile_id.split(":")\n if len(profile_id_parts) != 2:\n logger.error("Profile with id \'%s\' is invalid." % profile_id)\n continue\n@@ -131,8 +131,9 @@ def get_install_profile(self, product_id, allow_hidden=False):\n :returns: True on success, False otherwise.\n :rtype: boolean\n """\n- return self._get_profile(product_id, \'default\', strict=False,\n- allow_hidden=allow_hidden)\n+ return self._get_profile(\n+ product_id, "default", strict=False, allow_hidden=allow_hidden\n+ )\n \n def get_uninstall_profile(self, product_id):\n """Return the uninstall profile.\n@@ -140,7 +141,8 @@ def get_uninstall_profile(self, product_id):\n Note: not used yet.\n """\n return self._get_profile(\n- product_id, \'uninstall\', strict=True, allow_hidden=True)\n+ product_id, "uninstall", strict=True, allow_hidden=True\n+ )\n \n def is_product_installable(self, product_id, allow_hidden=False):\n """Does a product have an installation profile?\n@@ -157,19 +159,18 @@ def is_product_installable(self, product_id, allow_hidden=False):\n not_installable = []\n utils = getAllUtilitiesRegisteredFor(INonInstallable)\n for util in utils:\n- gnip = getattr(util, \'getNonInstallableProducts\', None)\n+ gnip = getattr(util, "getNonInstallableProducts", None)\n if gnip is None:\n continue\n not_installable.extend(gnip())\n if product_id in not_installable:\n return False\n \n- profile = self.get_install_profile(\n- product_id, allow_hidden=allow_hidden)\n+ profile = self.get_install_profile(product_id, allow_hidden=allow_hidden)\n if profile is None:\n return\n try:\n- self.ps.getProfileDependencyChain(profile[\'id\'])\n+ self.ps.getProfileDependencyChain(profile["id"])\n except KeyError as e:\n # Don\'t show twice the same error: old install and profile\n # oldinstall is test in first in other methods we may have an extra\n@@ -181,45 +182,38 @@ def is_product_installable(self, product_id, allow_hidden=False):\n # 3. Make sense of the next five lines: they remove \'Products.\'\n # when it is there, and add it when it is not???\n checkname = product_id\n- if checkname.startswith(\'Products.\'):\n+ if checkname.startswith("Products."):\n checkname = checkname[9:]\n else:\n- checkname = \'Products.\' + checkname\n+ checkname = "Products." + checkname\n if checkname in self.errors:\n- if self.errors[checkname][\'value\'] == e.args[0]:\n+ if self.errors[checkname]["value"] == e.args[0]:\n return False\n # A new error is found, register it\n self.errors[product_id] = dict(\n- type=_(\n- "dependency_missing",\n- default="Missing dependency"\n- ),\n+ type=_("dependency_missing", default="Missing dependency"),\n value=e.args[0],\n- product_id=product_id\n+ product_id=product_id,\n )\n else:\n self.errors[product_id] = dict(\n- type=_(\n- "dependency_missing",\n- default="Missing dependency"\n- ),\n+ type=_("dependency_missing", default="Missing dependency"),\n value=e.args[0],\n- product_id=product_id\n+ product_id=product_id,\n )\n return False\n return True\n \n def get_product_version(self, product_id):\n- """Return the version of the product (package).\n- """\n+ """Return the version of the product (package)."""\n try:\n dist = pkg_resources.get_distribution(product_id)\n return dist.version\n except pkg_resources.DistributionNotFound:\n- if \'.\' in product_id:\n- return \'\'\n+ if "." in product_id:\n+ return ""\n # For CMFPlacefulWorkflow we need to try Products.CMFPlacefulWorkflow.\n- return self.get_product_version(\'Products.\' + product_id)\n+ return self.get_product_version("Products." + product_id)\n \n def get_latest_upgrade_step(self, profile_id):\n """Get highest ordered upgrade step for profile.\n@@ -232,8 +226,7 @@ def get_latest_upgrade_step(self, profile_id):\n available = self.ps.listUpgrades(profile_id, True)\n if available: # could return empty sequence\n latest = available[-1]\n- profile_version = max(latest[\'dest\'],\n- key=pkg_resources.parse_version)\n+ profile_version = max(latest["dest"], key=pkg_resources.parse_version)\n except Exception:\n pass\n return profile_version\n@@ -256,21 +249,19 @@ def upgrade_info(self, product_id):\n if profile is None:\n # No GS profile, not supported.\n return {}\n- profile_id = profile[\'id\']\n+ profile_id = profile["id"]\n if not self.is_profile_installed(profile_id):\n return {}\n profile_version = str(self.ps.getVersionForProfile(profile_id))\n- if profile_version == \'latest\':\n+ if profile_version == "latest":\n profile_version = self.get_latest_upgrade_step(profile_id)\n if profile_version == UNKNOWN:\n # If a profile doesn\'t have a metadata.xml use the package version.\n profile_version = self.get_product_version(product_id)\n- installed_profile_version = self.ps.getLastVersionForProfile(\n- profile_id)\n+ installed_profile_version = self.ps.getLastVersionForProfile(profile_id)\n # getLastVersionForProfile returns the version as a tuple or unknown.\n if installed_profile_version != UNKNOWN:\n- installed_profile_version = str(\n- \'.\'.join(installed_profile_version))\n+ installed_profile_version = str(".".join(installed_profile_version))\n return dict(\n required=profile_version != installed_profile_version,\n available=len(self.ps.listUpgrades(profile_id)) > 0,\n@@ -288,7 +279,7 @@ def upgrade_product(self, product_id):\n if profile is None:\n logger.error("Could not upgrade %s, no profile.", product_id)\n return False\n- self.ps.upgradeProfile(profile[\'id\'])\n+ self.ps.upgradeProfile(profile["id"])\n return True\n \n def install_product(self, product_id, allow_hidden=False):\n@@ -304,26 +295,28 @@ def install_product(self, product_id, allow_hidden=False):\n :returns: True on success, False otherwise.\n :rtype: boolean\n """\n- profile = self.get_install_profile(\n- product_id, allow_hidden=allow_hidden)\n+ profile = self.get_install_profile(product_id, allow_hidden=allow_hidden)\n if not profile:\n logger.error("Could not install %s: no profile found.", product_id)\n # TODO Possibly raise an error.\n return False\n \n if self.is_product_installed(product_id):\n- logger.error("Could not install %s: profile already installed.",\n- product_id)\n+ logger.error("Could not install %s: profile already installed.", product_id)\n return False\n \n # Okay, actually install the profile.\n- profile_id = profile[\'id\']\n- self.ps.runAllImportStepsFromProfile(\'profile-%s\' % profile_id)\n+ profile_id = profile["id"]\n+ self.ps.runAllImportStepsFromProfile("profile-%s" % profile_id)\n \n if not self.is_profile_installed(profile_id):\n version = self.get_product_version(product_id)\n- logger.warning(\'Profile %s has no metadata.xml version. Falling back \'\n- \'to package version %s\', profile_id, version)\n+ logger.warning(\n+ "Profile %s has no metadata.xml version. Falling back "\n+ "to package version %s",\n+ profile_id,\n+ version,\n+ )\n self.ps.setLastVersionForProfile(profile_id, version)\n \n # No problems encountered.\n@@ -336,18 +329,17 @@ def uninstall_product(self, product_id):\n """\n profile = self.get_uninstall_profile(product_id)\n if not profile:\n- logger.error("Could not uninstall %s: no uninstall profile "\n- "found.", product_id)\n+ logger.error(\n+ "Could not uninstall %s: no uninstall profile " "found.", product_id\n+ )\n return False\n \n- self.ps.runAllImportStepsFromProfile(\n- \'profile-%s\' % profile[\'id\'])\n+ self.ps.runAllImportStepsFromProfile("profile-%s" % profile["id"])\n \n # Unmark the install profile.\n- install_profile = self.get_install_profile(\n- product_id, allow_hidden=True)\n+ install_profile = self.get_install_profile(product_id, allow_hidden=True)\n if install_profile:\n- self.ps.unsetLastVersionForProfile(install_profile[\'id\'])\n+ self.ps.unsetLastVersionForProfile(install_profile["id"])\n return True\n \n \n@@ -368,10 +360,10 @@ def marshall_addons(self):\n ignore_products = []\n utils = getAllUtilitiesRegisteredFor(INonInstallable)\n for util in utils:\n- ni_profiles = getattr(util, \'getNonInstallableProfiles\', None)\n+ ni_profiles = getattr(util, "getNonInstallableProfiles", None)\n if ni_profiles is not None:\n ignore_profiles.extend(ni_profiles())\n- ni_products = getattr(util, \'getNonInstallableProducts\', None)\n+ ni_products = getattr(util, "getNonInstallableProducts", None)\n if ni_products is not None:\n ignore_products.extend(ni_products())\n \n@@ -381,17 +373,17 @@ def marshall_addons(self):\n # applied already).\n # profiles_with_upgrades = self.ps.listProfilesWithUpgrades()\n for profile in profiles:\n- if profile[\'type\'] != EXTENSION:\n+ if profile["type"] != EXTENSION:\n continue\n \n- pid = profile[\'id\']\n+ pid = profile["id"]\n if pid in ignore_profiles:\n continue\n- pid_parts = pid.split(\':\')\n+ pid_parts = pid.split(":")\n if len(pid_parts) != 2:\n logger.error("Profile with id \'%s\' is invalid." % pid)\n # Which package (product) is this from?\n- product_id = profile[\'product\']\n+ product_id = profile["product"]\n if product_id in ignore_products:\n continue\n profile_type = pid_parts[-1]\n@@ -404,44 +396,46 @@ def marshall_addons(self):\n elif not self.is_product_installable(product_id):\n continue\n addons[product_id] = {\n- \'id\': product_id,\n- \'version\': self.get_product_version(product_id),\n- \'title\': product_id,\n- \'description\': \'\',\n- \'upgrade_profiles\': {},\n- \'other_profiles\': [],\n- \'install_profile\': None,\n- \'install_profile_id\': \'\',\n- \'uninstall_profile\': None,\n- \'uninstall_profile_id\': \'\',\n- \'is_installed\': installed,\n- \'upgrade_info\': upgrade_info,\n- \'profile_type\': profile_type,\n+ "id": product_id,\n+ "version": self.get_product_version(product_id),\n+ "title": product_id,\n+ "description": "",\n+ "upgrade_profiles": {},\n+ "other_profiles": [],\n+ "install_profile": None,\n+ "install_profile_id": "",\n+ "uninstall_profile": None,\n+ "uninstall_profile_id": "",\n+ "is_installed": installed,\n+ "upgrade_info": upgrade_info,\n+ "profile_type": profile_type,\n }\n # Add info on install and uninstall profile.\n product = addons[product_id]\n install_profile = self.get_install_profile(product_id)\n if install_profile is not None:\n- product[\'title\'] = install_profile[\'title\']\n- product[\'description\'] = install_profile[\'description\']\n- product[\'install_profile\'] = install_profile\n- product[\'install_profile_id\'] = install_profile[\'id\']\n- product[\'profile_type\'] = \'default\'\n+ product["title"] = install_profile["title"]\n+ product["description"] = install_profile["description"]\n+ product["install_profile"] = install_profile\n+ product["install_profile_id"] = install_profile["id"]\n+ product["profile_type"] = "default"\n uninstall_profile = self.get_uninstall_profile(product_id)\n if uninstall_profile is not None:\n- product[\'uninstall_profile\'] = uninstall_profile\n- product[\'uninstall_profile_id\'] = uninstall_profile[\'id\']\n+ product["uninstall_profile"] = uninstall_profile\n+ product["uninstall_profile_id"] = uninstall_profile["id"]\n # Do not override profile_type.\n- if not product[\'profile_type\']:\n- product[\'profile_type\'] = \'uninstall\'\n- if profile[\'id\'] in (product[\'install_profile_id\'],\n- product[\'uninstall_profile_id\']):\n+ if not product["profile_type"]:\n+ product["profile_type"] = "uninstall"\n+ if profile["id"] in (\n+ product["install_profile_id"],\n+ product["uninstall_profile_id"],\n+ ):\n # Everything has been done.\n continue\n- elif \'version\' in profile:\n- product[\'upgrade_profiles\'][profile[\'version\']] = profile\n+ elif "version" in profile:\n+ product["upgrade_profiles"][profile["version"]] = profile\n else:\n- product[\'other_profiles\'].append(profile)\n+ product["other_profiles"].append(profile)\n return addons\n \n def get_addons(self, apply_filter=None, product_name=None):\n@@ -462,27 +456,27 @@ def get_addons(self, apply_filter=None, product_name=None):\n """\n addons = self.marshall_addons()\n filtered = {}\n- if apply_filter == \'broken\':\n+ if apply_filter == "broken":\n all_broken = self.errors.values()\n for broken in all_broken:\n- filtered[broken[\'product_id\']] = broken\n+ filtered[broken["product_id"]] = broken\n else:\n for product_id, addon in addons.items():\n- if product_name and addon[\'id\'] != product_name:\n+ if product_name and addon["id"] != product_name:\n continue\n \n- installed = addon[\'is_installed\']\n- if apply_filter in [\'installed\', \'upgrades\'] and not installed:\n+ installed = addon["is_installed"]\n+ if apply_filter in ["installed", "upgrades"] and not installed:\n continue\n- elif apply_filter == \'available\':\n+ elif apply_filter == "available":\n if installed:\n continue\n # filter out upgrade profiles\n- if addon[\'profile_type\'] != \'default\':\n+ if addon["profile_type"] != "default":\n continue\n- elif apply_filter == \'upgrades\':\n- upgrade_info = addon[\'upgrade_info\']\n- if not upgrade_info.get(\'available\'):\n+ elif apply_filter == "upgrades":\n+ upgrade_info = addon["upgrade_info"]\n+ if not upgrade_info.get("available"):\n continue\n \n filtered[product_id] = addon\n@@ -491,22 +485,25 @@ def get_addons(self, apply_filter=None, product_name=None):\n \n def get_sorted_addon_values(self, apply_filter=None, product_name=None):\n values = self.get_addons(apply_filter, product_name).values()\n- return sorted(values, key=lambda x: translate(x.get(\'title\', \'\'), context=self.request).upper())\n+ return sorted(\n+ values,\n+ key=lambda x: translate(x.get("title", ""), context=self.request).upper(),\n+ )\n \n def get_upgrades(self):\n """\n Return a list of products that have upgrades on tap\n """\n- return self.get_sorted_addon_values(apply_filter=\'upgrades\')\n+ return self.get_sorted_addon_values(apply_filter="upgrades")\n \n def get_installed(self):\n- return self.get_sorted_addon_values(apply_filter=\'installed\')\n+ return self.get_sorted_addon_values(apply_filter="installed")\n \n def get_available(self):\n- return self.get_sorted_addon_values(apply_filter=\'available\')\n+ return self.get_sorted_addon_values(apply_filter="available")\n \n def get_broken(self):\n- return self.get_sorted_addon_values(apply_filter=\'broken\')\n+ return self.get_sorted_addon_values(apply_filter="broken")\n \n \n class UpgradeProductsView(InstallerView):\n@@ -515,73 +512,76 @@ class UpgradeProductsView(InstallerView):\n """\n \n def __call__(self):\n- products = self.request.get(\'prefs_reinstallProducts\', None)\n+ products = self.request.get("prefs_reinstallProducts", None)\n if products:\n messages = IStatusMessage(self.request)\n for product_id in products:\n result = self.upgrade_product(product_id)\n if not result:\n messages.addStatusMessage(\n- _(\'Error upgrading ${product}.\',\n- mapping={\'product\': product_id}), type="error")\n+ _(\n+ "Error upgrading ${product}.",\n+ mapping={"product": product_id},\n+ ),\n+ type="error",\n+ )\n # Abort changes for all upgrades.\n transaction.abort()\n break\n else:\n- messages.addStatusMessage(\n- _(\'Upgraded products.\'), type="info")\n+ messages.addStatusMessage(_("Upgraded products."), type="info")\n \n- purl = getToolByName(self.context, \'portal_url\')()\n- self.request.response.redirect(purl + \'/prefs_install_products_form\')\n+ purl = getToolByName(self.context, "portal_url")()\n+ self.request.response.redirect(purl + "/prefs_install_products_form")\n \n \n class InstallProductsView(InstallerView):\n-\n def __call__(self):\n- product_id = self.request.get(\'install_product\')\n+ product_id = self.request.get("install_product")\n if product_id:\n messages = IStatusMessage(self.request)\n- msg_type = \'info\'\n+ msg_type = "info"\n result = self.install_product(product_id)\n if result:\n- msg = _(\'Installed ${product}!\',\n- mapping={\'product\': product_id})\n+ msg = _("Installed ${product}!", mapping={"product": product_id})\n else:\n # Only reason should be that between loading the page and\n # clicking to install a product, another user has already\n # installed this product.\n- msg_type = \'error\'\n- msg = _(\'Failed to install ${product}.\',\n- mapping={\'product\': product_id})\n+ msg_type = "error"\n+ msg = _(\n+ "Failed to install ${product}.", mapping={"product": product_id}\n+ )\n messages.addStatusMessage(msg, type=msg_type)\n \n- purl = getToolByName(self.context, \'portal_url\')()\n- self.request.response.redirect(purl + \'/prefs_install_products_form\')\n+ purl = getToolByName(self.context, "portal_url")()\n+ self.request.response.redirect(purl + "/prefs_install_products_form")\n \n \n class UninstallProductsView(InstallerView):\n-\n def __call__(self):\n- product_id = self.request.get(\'uninstall_product\')\n+ product_id = self.request.get("uninstall_product")\n if product_id:\n messages = IStatusMessage(self.request)\n try:\n result = self.uninstall_product(product_id)\n except Exception as e:\n logger.error("Could not uninstall %s: %s", product_id, e)\n- msg_type = \'error\'\n- msg = _(\'Error uninstalling ${product}.\', mapping={\n- \'product\': product_id})\n+ msg_type = "error"\n+ msg = _(\n+ "Error uninstalling ${product}.", mapping={"product": product_id}\n+ )\n else:\n if result:\n- msg_type = \'info\'\n- msg = _(\'Uninstalled ${product}.\',\n- mapping={\'product\': product_id})\n+ msg_type = "info"\n+ msg = _("Uninstalled ${product}.", mapping={"product": product_id})\n else:\n- msg_type = \'error\'\n- msg = _(\'Could not uninstall ${product}.\',\n- mapping={\'product\': product_id})\n+ msg_type = "error"\n+ msg = _(\n+ "Could not uninstall ${product}.",\n+ mapping={"product": product_id},\n+ )\n messages.addStatusMessage(msg, type=msg_type)\n \n- purl = getToolByName(self.context, \'portal_url\')()\n- self.request.response.redirect(purl + \'/prefs_install_products_form\')\n+ purl = getToolByName(self.context, "portal_url")()\n+ self.request.response.redirect(purl + "/prefs_install_products_form")\ndiff --git a/Products/CMFPlone/controlpanel/browser/redirects.py b/Products/CMFPlone/controlpanel/browser/redirects.py\nindex 7216c4520c..5817ed038d 100644\n--- a/Products/CMFPlone/controlpanel/browser/redirects.py\n+++ b/Products/CMFPlone/controlpanel/browser/redirects.py\n@@ -28,7 +28,7 @@\n filestream_iterator = None\n \n \n-_ = MessageFactory(\'plone\')\n+_ = MessageFactory("plone")\n logger = logging.getLogger(__name__)\n \n \n@@ -56,18 +56,18 @@ def absolutize_path(path, is_source=True):\n err = _("You have to enter an alternative url.")\n else:\n err = _("You have to enter a target.")\n- elif not path.startswith(\'/\'):\n+ elif not path.startswith("/"):\n if is_source:\n err = _("Alternative url path must start with a slash.")\n else:\n # For targets, we accept external urls.\n # Do basic check.\n parsed = urlparse(path)\n- if parsed.scheme in (\'https\', \'http\') and parsed.netloc:\n+ if parsed.scheme in ("https", "http") and parsed.netloc:\n is_external_url = True\n else:\n err = _("Target path must start with a slash.")\n- elif \'@@\' in path:\n+ elif "@@" in path:\n if is_source:\n err = _("Alternative url path must not be a view.")\n else:\n@@ -76,7 +76,7 @@ def absolutize_path(path, is_source=True):\n context_path = "/".join(portal.getPhysicalPath())\n path = f"{context_path}{path}"\n if not err and not is_external_url:\n- catalog = getToolByName(portal, \'portal_catalog\')\n+ catalog = getToolByName(portal, "portal_catalog")\n if is_source:\n # Check whether already exists in storage\n storage = getUtility(IRedirectionStorage)\n@@ -105,13 +105,11 @@ def redirects(self):\n redirects = storage.redirects(context_path)\n for redirect in redirects:\n path = redirect[len(portal_path) :]\n- yield {\'redirect\': redirect, \'path\': path}\n+ yield {"redirect": redirect, "path": path}\n \n def edit_for_navigation_root(self, redirection):\n # Check navigation root\n- pps = getMultiAdapter(\n- (self.context, self.request), name=\'plone_portal_state\'\n- )\n+ pps = getMultiAdapter((self.context, self.request), name="plone_portal_state")\n nav_url = pps.navigation_root_url()\n portal_url = pps.portal_url()\n if nav_url != portal_url:\n@@ -119,7 +117,7 @@ def edit_for_navigation_root(self, redirection):\n # Update the path accordingly, unless the user already did this.\n extra = nav_url[len(portal_url) :]\n if not redirection.startswith(extra):\n- redirection = f\'{extra}{redirection}\'\n+ redirection = f"{extra}{redirection}"\n # Finally, return the (possibly edited) redirection\n return redirection\n \n@@ -130,52 +128,46 @@ def __call__(self):\n status = IStatusMessage(self.request)\n errors = {}\n \n- if \'form.button.Add\' in form:\n- redirection = form.get(\'redirection\')\n- if redirection and redirection.startswith(\'/\'):\n+ if "form.button.Add" in form:\n+ redirection = form.get("redirection")\n+ if redirection and redirection.startswith("/"):\n # Check navigation root\n redirection = self.edit_for_navigation_root(redirection)\n \n redirection, err = absolutize_path(redirection, is_source=True)\n if err:\n- errors[\'redirection\'] = err\n- status.addStatusMessage(err, type=\'error\')\n+ errors["redirection"] = err\n+ status.addStatusMessage(err, type="error")\n else:\n- del form[\'redirection\']\n+ del form["redirection"]\n storage.add(\n redirection,\n "/".join(self.context.getPhysicalPath()),\n manual=True,\n )\n- status.addStatusMessage(\n- _("Alternative url added."), type=\'info\'\n- )\n- elif \'form.button.Remove\' in form:\n- redirects = form.get(\'redirects\', ())\n+ status.addStatusMessage(_("Alternative url added."), type="info")\n+ elif "form.button.Remove" in form:\n+ redirects = form.get("redirects", ())\n for redirect in redirects:\n storage.remove(redirect)\n if len(redirects) > 1:\n- status.addStatusMessage(\n- _("Alternative urls removed."), type=\'info\'\n- )\n+ status.addStatusMessage(_("Alternative urls removed."), type="info")\n else:\n- status.addStatusMessage(\n- _("Alternative url removed."), type=\'info\'\n- )\n+ status.addStatusMessage(_("Alternative url removed."), type="info")\n \n return self.index(errors=errors)\n \n @memoize\n def view_url(self):\n- return self.context.absolute_url() + \'/@@manage-aliases\'\n+ return self.context.absolute_url() + "/@@manage-aliases"\n \n \n class RedirectionSet:\n- def __init__(self, query=\'\', created=\'\', manual=\'\'):\n+ def __init__(self, query="", created="", manual=""):\n self.storage = getUtility(IRedirectionStorage)\n \n portal = getSite()\n- self.portal_path = \'/\'.join(portal.getPhysicalPath())\n+ self.portal_path = "/".join(portal.getPhysicalPath())\n self.portal_path_len = len(self.portal_path)\n \n # noinspection PyProtectedMember\n@@ -184,34 +176,30 @@ def __init__(self, query=\'\', created=\'\', manual=\'\'):\n # min_k is /Plone/news and\n # max_k is /Plone/newt\n # Apparently that is the way to minize the keys we ask.\n- min_k = \'{:s}/{:s}\'.format(self.portal_path, query.strip(\'/\'))\n+ min_k = "{:s}/{:s}".format(self.portal_path, query.strip("/"))\n max_k = min_k[:-1] + chr(ord(min_k[-1]) + 1)\n- self.data = self.storage._paths.keys(\n- min=min_k, max=max_k, excludemax=True\n- )\n+ self.data = self.storage._paths.keys(min=min_k, max=max_k, excludemax=True)\n else:\n self.data = self.storage._paths.keys()\n if manual:\n # either \'yes\' or \'no\', otherwise we ignore the filter\n- if manual == \'yes\':\n+ if manual == "yes":\n manual = True\n- elif manual == \'no\':\n+ elif manual == "no":\n manual = False\n else:\n- manual = \'\'\n+ manual = ""\n if created:\n try:\n created = DateTime(created)\n except DateTimeError:\n- logger.warning(\n- \'Failed to parse as DateTime: %s\', created\n- )\n- created = \'\'\n- if created or manual != \'\':\n+ logger.warning("Failed to parse as DateTime: %s", created)\n+ created = ""\n+ if created or manual != "":\n chosen = []\n for redirect in self.data:\n info = self.storage.get_full(redirect)\n- if manual != \'\':\n+ if manual != "":\n if info[2] != manual:\n continue\n if created and info[1]:\n@@ -235,22 +223,20 @@ def __getitem__(self, item):\n if redirect_to.startswith(self.portal_path):\n redirect_to = redirect_to[self.portal_path_len :]\n return {\n- \'redirect\': redirect,\n- \'path\': path,\n- \'redirect-to\': redirect_to,\n- \'datetime\': info[1],\n- \'manual\': info[2],\n+ "redirect": redirect,\n+ "path": path,\n+ "redirect-to": redirect_to,\n+ "datetime": info[1],\n+ "manual": info[2],\n }\n \n \n class RedirectsBatchView(PloneBatchView):\n def make_link(self, pagenumber=None, omit_params=None):\n if omit_params is None:\n- omit_params = [\'ajax_load\']\n- url = super().make_link(\n- pagenumber, omit_params\n- )\n- return f\'{url:s}#manage-existing-aliases\'\n+ omit_params = ["ajax_load"]\n+ url = super().make_link(pagenumber, omit_params)\n+ return f"{url:s}#manage-existing-aliases"\n \n \n class RedirectsControlPanel(BrowserView):\n@@ -259,21 +245,21 @@ def batching(self):\n \n @memoize\n def redirects(self):\n- """ Get existing redirects from the redirection storage.\n- Return dict with the strings redirect, path and redirect-to.\n- Strip the id of the instance from path and redirect-to if\n- it is present. (Seems to be always true)\n- If id of instance is not present in path the var \'path\' and\n- \'redirect\' are equal.\n+ """Get existing redirects from the redirection storage.\n+ Return dict with the strings redirect, path and redirect-to.\n+ Strip the id of the instance from path and redirect-to if\n+ it is present. (Seems to be always true)\n+ If id of instance is not present in path the var \'path\' and\n+ \'redirect\' are equal.\n """\n return Batch(\n RedirectionSet(\n- query=self.request.form.get(\'q\', \'\'),\n- created=self.request.form.get(\'datetime\', \'\'),\n- manual=self.request.form.get(\'manual\', \'\'),\n+ query=self.request.form.get("q", ""),\n+ created=self.request.form.get("datetime", ""),\n+ manual=self.request.form.get("manual", ""),\n ),\n- int(self.request.form.get(\'b_size\', \'15\')),\n- int(self.request.form.get(\'b_start\', \'0\')),\n+ int(self.request.form.get("b_size", "15")),\n+ int(self.request.form.get("b_start", "0")),\n orphan=1,\n )\n \n@@ -288,17 +274,15 @@ def __call__(self):\n self.csv_errors = []\n self.form_errors = {}\n \n- if \'form.button.Remove\' in form or \'form.button.MatchRemove\' in form:\n- if \'form.button.Remove\' in form:\n- redirects = form.get(\'redirects\', ())\n+ if "form.button.Remove" in form or "form.button.MatchRemove" in form:\n+ if "form.button.Remove" in form:\n+ redirects = form.get("redirects", ())\n else:\n- query = self.request.form.get(\'q\', \'\')\n- created = self.request.form.get(\'datetime\', \'\')\n- manual = self.request.form.get(\'manual\', \'\')\n- if created or manual or (query and query != \'/\'):\n- rset = RedirectionSet(\n- query=query, created=created, manual=manual\n- )\n+ query = self.request.form.get("q", "")\n+ created = self.request.form.get("datetime", "")\n+ manual = self.request.form.get("manual", "")\n+ if created or manual or (query and query != "/"):\n+ rset = RedirectionSet(query=query, created=created, manual=manual)\n redirects = list(rset.data)\n else:\n redirects = []\n@@ -306,31 +290,27 @@ def __call__(self):\n storage.remove(redirect)\n if len(redirects) == 0:\n err = _("No alternative urls selected for removal.")\n- status.addStatusMessage(err, type=\'error\')\n- self.form_errors[\'remove_redirects\'] = err\n+ status.addStatusMessage(err, type="error")\n+ self.form_errors["remove_redirects"] = err\n elif len(redirects) > 1:\n- status.addStatusMessage(\n- _("Alternative urls removed."), type=\'info\'\n- )\n+ status.addStatusMessage(_("Alternative urls removed."), type="info")\n else:\n- status.addStatusMessage(\n- _("Alternative url removed."), type=\'info\'\n- )\n- elif \'form.button.Add\' in form:\n+ status.addStatusMessage(_("Alternative url removed."), type="info")\n+ elif "form.button.Add" in form:\n err = self.add(\n- form[\'redirection\'],\n- form[\'target_path\'],\n+ form["redirection"],\n+ form["target_path"],\n portal,\n storage,\n status,\n )\n if not err:\n # clear our the form\n- del form[\'redirection\']\n- del form[\'target_path\']\n- elif \'form.button.Upload\' in form:\n- self.upload(form[\'file\'], portal, storage, status)\n- elif \'form.button.Download\' in form:\n+ del form["redirection"]\n+ del form["target_path"]\n+ elif "form.button.Upload" in form:\n+ self.upload(form["file"], portal, storage, status)\n+ elif "form.button.Download" in form:\n return self.download()\n \n return self.index()\n@@ -342,10 +322,10 @@ def add(self, redirection, target, portal, storage, status):\n """\n abs_redirection, err = absolutize_path(redirection, is_source=True)\n if err:\n- self.form_errors[\'redirection\'] = err\n+ self.form_errors["redirection"] = err\n abs_target, target_err = absolutize_path(target, is_source=False)\n if target_err:\n- self.form_errors[\'target_path\'] = target_err\n+ self.form_errors["target_path"] = target_err\n \n if err and target_err:\n err = f"{err} {target_err}"\n@@ -360,14 +340,14 @@ def add(self, redirection, target, portal, storage, status):\n # TODO: detect indirect recursion\n \n if err:\n- status.addStatusMessage(_(err), type=\'error\')\n+ status.addStatusMessage(_(err), type="error")\n else:\n storage.add(abs_redirection, abs_target, manual=True)\n status.addStatusMessage(\n _("Alternative url from {0} to {1} added.").format(\n abs_redirection, abs_target\n ),\n- type=\'info\',\n+ type="info",\n )\n return err\n \n@@ -377,13 +357,13 @@ def upload(self, file, portal, storage, status):\n # No file picked. Theres gotta be a better way to handle this.\n if not file.filename:\n err = _("Please pick a file to upload.")\n- status.addStatusMessage(err, type=\'error\')\n- self.form_errors[\'file\'] = err\n+ status.addStatusMessage(err, type="error")\n+ self.form_errors["file"] = err\n return\n # Turn all kinds of newlines into LF ones. The csv module doesn\'t do\n # its own newline sniffing and requires either \\n or \\r.\n contents = safe_text(file.read()).splitlines()\n- file = StringIO(\'\\n\'.join(contents))\n+ file = StringIO("\\n".join(contents))\n \n # Use first two lines as a representative sample for guessing format,\n # in case one is a bunch of headers.\n@@ -406,28 +386,22 @@ def upload(self, file, portal, storage, status):\n try:\n now = DateTime(dt)\n except DateTimeError:\n- logger.warning(\n- \'Failed to parse as DateTime: %s\', dt\n- )\n+ logger.warning("Failed to parse as DateTime: %s", dt)\n now = None\n if len(fields) >= 4:\n manual = fields[3].lower()\n # Compare first character with false, no, 0.\n- if manual and manual[0] in \'fn0\':\n+ if manual and manual[0] in "fn0":\n manual = False\n else:\n manual = True\n- abs_redirection, err = absolutize_path(\n- redirection, is_source=True\n- )\n- abs_target, target_err = absolutize_path(\n- target, is_source=False\n- )\n+ abs_redirection, err = absolutize_path(redirection, is_source=True)\n+ abs_target, target_err = absolutize_path(target, is_source=False)\n if err and target_err:\n if (\n i == 0\n- and not redirection.startswith(\'/\')\n- and not target.startswith(\'/\')\n+ and not redirection.startswith("/")\n+ and not target.startswith("/")\n ):\n # First line is a header. Ignore this.\n continue\n@@ -462,20 +436,20 @@ def upload(self, file, portal, storage, status):\n status.addStatusMessage(\n _(\n "${count} alternative urls added.",\n- mapping={\'count\': len(successes)},\n+ mapping={"count": len(successes)},\n ),\n- type=\'info\',\n+ type="info",\n )\n else:\n self.csv_errors.insert(\n 0,\n dict(\n line_number=0,\n- line=\'\',\n+ line="",\n message=_(\n- \'msg_delimiter\',\n+ "msg_delimiter",\n default="Delimiter detected: ${delimiter}",\n- mapping={\'delimiter\': dialect.delimiter},\n+ mapping={"delimiter": dialect.delimiter},\n ),\n ),\n )\n@@ -490,11 +464,11 @@ def download(self):\n portal_path = "/".join(portal.getPhysicalPath())\n len_portal_path = len(portal_path)\n file_descriptor, file_path = tempfile.mkstemp(\n- suffix=\'.csv\', prefix=\'redirects_\'\n+ suffix=".csv", prefix="redirects_"\n )\n- with open(file_path, \'w\') as stream:\n+ with open(file_path, "w") as stream:\n csv_writer = writer(stream)\n- csv_writer.writerow((\'old path\', \'new path\', \'datetime\', \'manual\'))\n+ csv_writer.writerow(("old path", "new path", "datetime", "manual"))\n storage = getUtility(IRedirectionStorage)\n paths = storage._paths\n # Note that the old and new paths start with /plone-site-id.\n@@ -517,18 +491,16 @@ def download(self):\n length = len(contents)\n \n response = self.request.response\n- response.setHeader(\'Content-Type\', \'text/csv\')\n- response.setHeader(\'Content-Length\', length)\n- response.setHeader(\n- \'Content-Disposition\', \'attachment; filename=redirects.csv\'\n- )\n+ response.setHeader("Content-Type", "text/csv")\n+ response.setHeader("Content-Length", length)\n+ response.setHeader("Content-Disposition", "attachment; filename=redirects.csv")\n if filestream_iterator is None:\n return contents\n # TODO: this is not enough to really stream the file.\n # I think we would need to handle Request-Range, like in the old\n # plone.app.blob.download.handleRequestRange\n- return filestream_iterator(file_path, \'rb\')\n+ return filestream_iterator(file_path, "rb")\n \n @memoize\n def view_url(self):\n- return self.context.absolute_url() + \'/@@redirection-controlpanel\'\n+ return self.context.absolute_url() + "/@@redirection-controlpanel"\ndiff --git a/Products/CMFPlone/controlpanel/browser/relations.py b/Products/CMFPlone/controlpanel/browser/relations.py\nindex 843623f4aa..1cbf677b02 100644\n--- a/Products/CMFPlone/controlpanel/browser/relations.py\n+++ b/Products/CMFPlone/controlpanel/browser/relations.py\n@@ -20,38 +20,40 @@\n \n \n class RelationsRebuildControlpanel(BrowserView):\n-\n def __call__(self, rebuild=False, flush_and_rebuild_intids=False):\n self.done = False\n if rebuild:\n rebuild_relations(flush_and_rebuild_intids=flush_and_rebuild_intids)\n self.done = True\n IStatusMessage(self.request).addStatusMessage(\n- _(\'Finished! See log for details.\'), \'info\')\n+ _("Finished! See log for details."), "info"\n+ )\n \n self.relations_stats, self.broken = get_relations_stats()\n return self.index()\n \n \n class RelationsInspectControlpanel(BrowserView):\n-\n def __call__(self, relation=None, inspect_backrelation=False):\n- self.relation = relation or self.request.get(\'relation\')\n- self.inspect_backrelation = inspect_backrelation or self.request.get(\'inspect_backrelation\')\n+ self.relation = relation or self.request.get("relation")\n+ self.inspect_backrelation = inspect_backrelation or self.request.get(\n+ "inspect_backrelation"\n+ )\n \n self.relations = []\n self.relations_stats, self.broken = get_relations_stats()\n registry = getUtility(IRegistry)\n- view_action = registry[\'plone.types_use_view_action_in_listings\']\n+ view_action = registry["plone.types_use_view_action_in_listings"]\n \n if not self.relation:\n IStatusMessage(self.request).addStatusMessage(\n- _(\'Please select a relation\'), \'info\')\n+ _("Please select a relation"), "info"\n+ )\n return self.index()\n \n intids = queryUtility(IIntIds)\n relation_catalog = getUtility(ICatalog)\n- query = {\'from_attribute\': self.relation}\n+ query = {"from_attribute": self.relation}\n info = defaultdict(list)\n \n # relations: column_1 = source, column_2 = target(s)\n@@ -60,8 +62,8 @@ def __call__(self, relation=None, inspect_backrelation=False):\n if rel.isBroken():\n continue\n try:\n- hasattr(rel, \'from_id\')\n- hasattr(rel, \'to_id\')\n+ hasattr(rel, "from_id")\n+ hasattr(rel, "to_id")\n except IntIdMissingError:\n continue\n if self.inspect_backrelation:\n@@ -72,23 +74,31 @@ def __call__(self, relation=None, inspect_backrelation=False):\n for column_1_intid in info:\n obj = intids.getObject(column_1_intid)\n use_view_action = obj.portal_type in view_action\n- url = obj.absolute_url() + \'/view\' if use_view_action else obj.absolute_url()\n+ url = (\n+ obj.absolute_url() + "/view" if use_view_action else obj.absolute_url()\n+ )\n item = {}\n- item[\'column_1\'] = {\n- \'title\': obj.title_or_id(),\n- \'url\': url,\n- \'portal_type\': obj.portal_type,\n+ item["column_1"] = {\n+ "title": obj.title_or_id(),\n+ "url": url,\n+ "portal_type": obj.portal_type,\n }\n- item[\'column_2\'] = []\n+ item["column_2"] = []\n for column_2_intid in info[column_1_intid]:\n obj = intids.getObject(column_2_intid)\n use_view_action = obj.portal_type in view_action\n- url = obj.absolute_url() + \'/view\' if use_view_action else obj.absolute_url()\n- item[\'column_2\'].append({\n- \'title\': obj.title_or_id(),\n- \'url\': url,\n- \'portal_type\': obj.portal_type,\n- })\n+ url = (\n+ obj.absolute_url() + "/view"\n+ if use_view_action\n+ else obj.absolute_url()\n+ )\n+ item["column_2"].append(\n+ {\n+ "title": obj.title_or_id(),\n+ "url": url,\n+ "portal_type": obj.portal_type,\n+ }\n+ )\n self.relations.append(item)\n- self.relations.sort(key=lambda x: x[\'column_1\'][\'title\'])\n+ self.relations.sort(key=lambda x: x["column_1"]["title"])\n return self.index()\ndiff --git a/Products/CMFPlone/controlpanel/browser/resourceregistry.py b/Products/CMFPlone/controlpanel/browser/resourceregistry.py\nindex 4277e9d221..9cca60a22f 100644\n--- a/Products/CMFPlone/controlpanel/browser/resourceregistry.py\n+++ b/Products/CMFPlone/controlpanel/browser/resourceregistry.py\n@@ -94,7 +94,11 @@ def _update(self):\n return\n if new_name in bundles:\n IStatusMessage(self.request).addStatusMessage(\n- _("Record name ${new_name} already taken.", mapping=dict(new_name=new_name)), "error"\n+ _(\n+ "Record name ${new_name} already taken.",\n+ mapping=dict(new_name=new_name),\n+ ),\n+ "error",\n )\n return\n record = bundles[original_name]\ndiff --git a/Products/CMFPlone/controlpanel/browser/search.py b/Products/CMFPlone/controlpanel/browser/search.py\nindex 063e893c18..d87c285463 100644\n--- a/Products/CMFPlone/controlpanel/browser/search.py\n+++ b/Products/CMFPlone/controlpanel/browser/search.py\n@@ -7,7 +7,6 @@\n \n \n class SearchControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "SearchControlPanel"\n label = _("Search Settings")\n schema = ISearchSchema\n@@ -15,35 +14,38 @@ class SearchControlPanelForm(controlpanel.RegistryEditForm):\n \n def updateFields(self):\n super().updateFields()\n- self.fields[\'types_not_searched\'].widgetFactory = \\\n- CheckBoxFieldWidget\n+ self.fields["types_not_searched"].widgetFactory = CheckBoxFieldWidget\n \n def updateWidgets(self):\n super().updateWidgets()\n # Replace vocabulary for \'types_not_searched\' with user friendly types\n # to hide "bad" types in control panel.\n vocab = self._friendly_types_vocabulary()\n- self.widgets[\'types_not_searched\'].terms.terms = vocab(self.context)\n- self.widgets[\'types_not_searched\'].update()\n+ self.widgets["types_not_searched"].terms.terms = vocab(self.context)\n+ self.widgets["types_not_searched"].update()\n \n def applyChanges(self, data):\n # We only get "friendly" types. Add "bad" types from current settings.\n- current_types = self.fields[\'types_not_searched\'].field.get(\n- self.getContent())\n- all_vocab = queryUtility(IVocabularyFactory,\n- \'plone.app.vocabularies.PortalTypes\')\n+ current_types = self.fields["types_not_searched"].field.get(self.getContent())\n+ all_vocab = queryUtility(\n+ IVocabularyFactory, "plone.app.vocabularies.PortalTypes"\n+ )\n all_types = [t.value for t in all_vocab(self.context)]\n friendly_vocab = self._friendly_types_vocabulary()\n friendly_types = [t.value for t in friendly_vocab(self.context)]\n- submitted_types = data[\'types_not_searched\'] or []\n- new_types = [t for t in all_types if t in submitted_types\n- or (t in current_types and t not in friendly_types)]\n- data[\'types_not_searched\'] = tuple(new_types)\n+ submitted_types = data["types_not_searched"] or []\n+ new_types = [\n+ t\n+ for t in all_types\n+ if t in submitted_types or (t in current_types and t not in friendly_types)\n+ ]\n+ data["types_not_searched"] = tuple(new_types)\n super().applyChanges(data)\n \n def _friendly_types_vocabulary(self):\n- return queryUtility(IVocabularyFactory,\n- \'plone.app.vocabularies.ReallyUserFriendlyTypes\')\n+ return queryUtility(\n+ IVocabularyFactory, "plone.app.vocabularies.ReallyUserFriendlyTypes"\n+ )\n \n \n class SearchControlPanel(controlpanel.ControlPanelFormWrapper):\ndiff --git a/Products/CMFPlone/controlpanel/browser/security.py b/Products/CMFPlone/controlpanel/browser/security.py\nindex 170457ef2c..5a2241346e 100644\n--- a/Products/CMFPlone/controlpanel/browser/security.py\n+++ b/Products/CMFPlone/controlpanel/browser/security.py\n@@ -11,11 +11,10 @@\n import logging\n \n \n-logger = logging.getLogger(\'Products.CMFPlone\')\n+logger = logging.getLogger("Products.CMFPlone")\n \n \n class SecurityControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "SecurityControlPanel"\n label = _("Security Settings")\n schema = ISecuritySchema\n@@ -37,33 +36,32 @@ class EmailLogin(BrowserView):\n duplicates = []\n \n def __call__(self):\n- if self.request.form.get(\'check_email\'):\n+ if self.request.form.get("check_email"):\n self.duplicates = self.check_email()\n- elif self.request.form.get(\'check_userid\'):\n+ elif self.request.form.get("check_userid"):\n self.duplicates = self.check_userid()\n return self.index()\n \n @property\n def _email_list(self):\n context = aq_inner(self.context)\n- pas = getToolByName(context, \'acl_users\')\n+ pas = getToolByName(context, "acl_users")\n emails = defaultdict(list)\n orig_transform = pas.login_transform\n try:\n if not orig_transform:\n # Temporarily set this to lower, as that will happen\n # when turning emaillogin on.\n- pas.login_transform = \'lower\'\n+ pas.login_transform = "lower"\n for user in pas.getUsers():\n if user is None:\n # Created in the ZMI?\n continue\n- email = user.getProperty(\'email\', \'\')\n+ email = user.getProperty("email", "")\n if email:\n email = pas.applyTransform(email)\n else:\n- logger.warning("User %s has no email address.",\n- user.getUserId())\n+ logger.warning("User %s has no email address.", user.getUserId())\n # Add the normal login name anyway.\n email = pas.applyTransform(user.getUserName())\n emails[email].append(user.getUserId())\n@@ -75,8 +73,9 @@ def check_email(self):\n duplicates = []\n for email, userids in self._email_list.items():\n if len(userids) > 1:\n- logger.warning("Duplicate accounts for email address %s: %r",\n- email, userids)\n+ logger.warning(\n+ "Duplicate accounts for email address %s: %r", email, userids\n+ )\n duplicates.append((email, userids))\n \n return duplicates\n@@ -86,14 +85,14 @@ def _userid_list(self):\n # user ids are unique, but their lowercase version might not\n # be unique.\n context = aq_inner(self.context)\n- pas = getToolByName(context, \'acl_users\')\n+ pas = getToolByName(context, "acl_users")\n userids = defaultdict(list)\n orig_transform = pas.login_transform\n try:\n if not orig_transform:\n # Temporarily set this to lower, as that will happen\n # when turning emaillogin on.\n- pas.login_transform = \'lower\'\n+ pas.login_transform = "lower"\n for user in pas.getUsers():\n if user is None:\n continue\n@@ -107,8 +106,11 @@ def check_userid(self):\n duplicates = []\n for login_name, userids in self._userid_list.items():\n if len(userids) > 1:\n- logger.warning("Duplicate accounts for lower case user id "\n- "%s: %r", login_name, userids)\n+ logger.warning(\n+ "Duplicate accounts for lower case user id " "%s: %r",\n+ login_name,\n+ userids,\n+ )\n duplicates.append((login_name, userids))\n \n return duplicates\ndiff --git a/Products/CMFPlone/controlpanel/browser/site.py b/Products/CMFPlone/controlpanel/browser/site.py\nindex 0d17b21558..f5f1bc0c21 100644\n--- a/Products/CMFPlone/controlpanel/browser/site.py\n+++ b/Products/CMFPlone/controlpanel/browser/site.py\n@@ -6,7 +6,6 @@\n \n \n class SiteControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "SiteControlPanel"\n label = _("Site Settings")\n description = _("Site-wide settings.")\n@@ -15,13 +14,13 @@ class SiteControlPanelForm(controlpanel.RegistryEditForm):\n \n def updateFields(self):\n super().updateFields()\n- self.fields[\'site_logo\'].widgetFactory = NamedImageFieldWidget\n- self.fields[\'site_favicon\'].widgetFactory = NamedImageFieldWidget\n+ self.fields["site_logo"].widgetFactory = NamedImageFieldWidget\n+ self.fields["site_favicon"].widgetFactory = NamedImageFieldWidget\n \n def updateWidgets(self):\n super().updateWidgets()\n # hide the default_page field/widgets\n- self.widgets[\'default_page\'].mode = interfaces.HIDDEN_MODE\n+ self.widgets["default_page"].mode = interfaces.HIDDEN_MODE\n \n \n class SiteControlPanel(controlpanel.ControlPanelFormWrapper):\ndiff --git a/Products/CMFPlone/controlpanel/browser/socialmedia.py b/Products/CMFPlone/controlpanel/browser/socialmedia.py\nindex 6cdb1ef2ed..aed9800f74 100644\n--- a/Products/CMFPlone/controlpanel/browser/socialmedia.py\n+++ b/Products/CMFPlone/controlpanel/browser/socialmedia.py\n@@ -4,7 +4,6 @@\n \n \n class SocialControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "SocialControlPanel"\n label = _("Social Media Settings")\n description = _("Social media sharing settings.")\ndiff --git a/Products/CMFPlone/controlpanel/browser/syndication.py b/Products/CMFPlone/controlpanel/browser/syndication.py\nindex 452ec185da..a34305772e 100644\n--- a/Products/CMFPlone/controlpanel/browser/syndication.py\n+++ b/Products/CMFPlone/controlpanel/browser/syndication.py\n@@ -7,45 +7,47 @@\n from zope.i18nmessageid import MessageFactory\n \n \n-_ = MessageFactory(\'plone\')\n+_ = MessageFactory("plone")\n \n \n class SyndicationControlPanelForm(controlpanel.RegistryEditForm):\n schema = ISiteSyndicationSettings\n- label = _(\'Syndication Settings\')\n- description = _(\'Default syndication settings.\')\n+ label = _("Syndication Settings")\n+ description = _("Default syndication settings.")\n \n def updateFields(self):\n super().updateFields()\n- self.fields[\'site_rss_items\'].widgetFactory = SelectFieldWidget\n+ self.fields["site_rss_items"].widgetFactory = SelectFieldWidget\n \n def getSyndicationSettingsButtonShown(self):\n- actions = getToolByName(self.context, \'portal_actions\')\n- if \'syndication\' in actions.object.objectIds():\n- return actions.object.syndication.getProperty(\'visible\')\n+ actions = getToolByName(self.context, "portal_actions")\n+ if "syndication" in actions.object.objectIds():\n+ return actions.object.syndication.getProperty("visible")\n else:\n IStatusMessage(self.request).addStatusMessage(\n- _("Missing syndication settings action."), "warn")\n+ _("Missing syndication settings action."), "warn"\n+ )\n \n def getSyndicationLinkShown(self):\n- actions = getToolByName(self.context, \'portal_actions\')\n- if \'rss\' in actions.document_actions.objectIds():\n- return actions.document_actions.rss.getProperty(\'visible\')\n+ actions = getToolByName(self.context, "portal_actions")\n+ if "rss" in actions.document_actions.objectIds():\n+ return actions.document_actions.rss.getProperty("visible")\n else:\n IStatusMessage(self.request).addStatusMessage(\n- _("Missing rss link action."), "warn")\n+ _("Missing rss link action."), "warn"\n+ )\n \n def forceCheckboxValue(self, widget, checked):\n if checked:\n- widget.value = [\'selected\']\n+ widget.value = ["selected"]\n else:\n widget.value = []\n for item in widget.items:\n- if \'checked\' in item:\n+ if "checked" in item:\n if checked:\n- item[\'checked\'] = True\n+ item["checked"] = True\n else:\n- item[\'checked\'] = False\n+ item["checked"] = False\n \n def update(self):\n super().update()\n@@ -56,22 +58,26 @@ def update(self):\n show_settings_btn = self.getSyndicationSettingsButtonShown()\n if show_settings_btn != content.show_syndication_button:\n self.forceCheckboxValue(\n- self.widgets[\'show_syndication_button\'], show_settings_btn)\n+ self.widgets["show_syndication_button"], show_settings_btn\n+ )\n show_link_btn = self.getSyndicationLinkShown()\n if show_link_btn != content.show_syndication_link:\n self.forceCheckboxValue(\n- self.widgets[\'show_syndication_link\'], show_link_btn)\n+ self.widgets["show_syndication_link"], show_link_btn\n+ )\n \n def setSyndicationActionSettings(self, data):\n- actions = getToolByName(self.context, \'portal_actions\')\n- if \'syndication\' in actions.object.objectIds():\n+ actions = getToolByName(self.context, "portal_actions")\n+ if "syndication" in actions.object.objectIds():\n actions.object.syndication._setPropValue(\n- \'visible\', data[\'show_syndication_button\'])\n- if \'rss\' in actions.document_actions.objectIds():\n+ "visible", data["show_syndication_button"]\n+ )\n+ if "rss" in actions.document_actions.objectIds():\n actions.document_actions.rss._setPropValue(\n- \'visible\', data[\'show_syndication_link\'])\n+ "visible", data["show_syndication_link"]\n+ )\n \n- @button.buttonAndHandler(_("Save"), name=\'save\')\n+ @button.buttonAndHandler(_("Save"), name="save")\n def handleSave(self, action):\n """\n Again, we\'re customizing this to handle saving\n@@ -84,14 +90,12 @@ def handleSave(self, action):\n \n self.setSyndicationActionSettings(data)\n self.applyChanges(data)\n- IStatusMessage(self.request).addStatusMessage(\n- _("Changes saved."), "info")\n+ IStatusMessage(self.request).addStatusMessage(_("Changes saved."), "info")\n self.request.response.redirect(self.request.getURL())\n \n- @button.buttonAndHandler(_("Cancel"), name=\'cancel\')\n+ @button.buttonAndHandler(_("Cancel"), name="cancel")\n def handleCancel(self, action):\n- IStatusMessage(self.request).addStatusMessage(\n- _("Edit cancelled."), "info")\n+ IStatusMessage(self.request).addStatusMessage(_("Edit cancelled."), "info")\n self.request.response.redirect(self.request.getURL())\n \n \ndiff --git a/Products/CMFPlone/controlpanel/browser/tinymce.py b/Products/CMFPlone/controlpanel/browser/tinymce.py\nindex b286e71464..a7cd3e97ee 100644\n--- a/Products/CMFPlone/controlpanel/browser/tinymce.py\n+++ b/Products/CMFPlone/controlpanel/browser/tinymce.py\n@@ -32,18 +32,21 @@ class TinyMCEAdvancedForm(group.GroupForm):\n \n \n class TinyMCEControlPanelForm(controlpanel.RegistryEditForm):\n-\n id = "TinyMCEControlPanel"\n label = _("TinyMCE Settings")\n schema = ITinyMCESchema\n schema_prefix = "plone"\n fields = field.Fields(ITinyMCELayoutSchema)\n- groups = (TinyMCEPluginForm, TinyMCESpellCheckerForm,\n- TinyMCEResourceTypesForm, TinyMCEAdvancedForm)\n+ groups = (\n+ TinyMCEPluginForm,\n+ TinyMCESpellCheckerForm,\n+ TinyMCEResourceTypesForm,\n+ TinyMCEAdvancedForm,\n+ )\n \n def updateFields(self):\n super().updateFields()\n- self.groups[0].fields[\'plugins\'].widgetFactory = CheckBoxFieldWidget\n+ self.groups[0].fields["plugins"].widgetFactory = CheckBoxFieldWidget\n \n \n class TinyMCEControlPanel(controlpanel.ControlPanelFormWrapper):\ndiff --git a/Products/CMFPlone/controlpanel/browser/types.py b/Products/CMFPlone/controlpanel/browser/types.py\nindex b98fe6c347..c992fbc1ec 100644\n--- a/Products/CMFPlone/controlpanel/browser/types.py\n+++ b/Products/CMFPlone/controlpanel/browser/types.py\n@@ -23,26 +23,23 @@\n \n def format_description(text, request=None):\n # We expect the workflow to be a text of \'- \' divided bullet points.\n- text = translate(text.strip(), domain=\'plone\', context=request)\n- return [s.strip() for s in text.split(\'- \') if s]\n+ text = translate(text.strip(), domain="plone", context=request)\n+ return [s.strip() for s in text.split("- ") if s]\n \n \n # These are convenient / user friendly versioning policies.\n VERSION_POLICIES = [\n- dict(id="off",\n- policy=(),\n- title=_("versioning_off",\n- default="No versioning")),\n-\n- dict(id="manual",\n- policy=("version_on_revert",),\n- title=_("versioning_manual",\n- default="Manual")),\n-\n- dict(id="automatic",\n- policy=("at_edit_autoversion", "version_on_revert"),\n- title=_("versioning_automatic",\n- default="Automatic")),\n+ dict(id="off", policy=(), title=_("versioning_off", default="No versioning")),\n+ dict(\n+ id="manual",\n+ policy=("version_on_revert",),\n+ title=_("versioning_manual", default="Manual"),\n+ ),\n+ dict(\n+ id="automatic",\n+ policy=("at_edit_autoversion", "version_on_revert"),\n+ title=_("versioning_automatic", default="Automatic"),\n+ ),\n ]\n \n \n@@ -53,38 +50,36 @@ class TypesControlPanel(AutoExtensibleForm, form.EditForm):\n description = _("General types settings.")\n form_name = _("Types settings")\n control_panel_view = "content-controlpanel"\n- template = ViewPageTemplateFile(\'types.pt\')\n- behavior_name = \'plone.versioning\'\n+ template = ViewPageTemplateFile("types.pt")\n+ behavior_name = "plone.versioning"\n \n- @button.buttonAndHandler(_(\'Save\'), name=\'save\')\n+ @button.buttonAndHandler(_("Save"), name="save")\n def handleSave(self, action):\n data, errors = self.extractData()\n if errors:\n self.status = self.formErrorsMessage\n return\n- IStatusMessage(self.request).addStatusMessage(\n- _("Changes saved"), "info")\n+ IStatusMessage(self.request).addStatusMessage(_("Changes saved"), "info")\n self.request.response.redirect("@@content-controlpanel")\n \n- @button.buttonAndHandler(_("Cancel"), name=\'cancel\')\n+ @button.buttonAndHandler(_("Cancel"), name="cancel")\n def handleCancel(self, action):\n- IStatusMessage(self.request).addStatusMessage(\n- _("Changes canceled."), "info")\n+ IStatusMessage(self.request).addStatusMessage(_("Changes canceled."), "info")\n self.request.response.redirect("@@overview-controlpanel")\n \n @property\n @memoize\n def type_id(self):\n- type_id = self.request.get(\'type_id\', None)\n+ type_id = self.request.get("type_id", None)\n if type_id is None:\n- type_id = \'\'\n+ type_id = ""\n return type_id\n \n @property\n @memoize\n def fti(self):\n type_id = self.type_id\n- portal_types = getToolByName(self.context, \'portal_types\')\n+ portal_types = getToolByName(self.context, "portal_types")\n return getattr(portal_types, type_id)\n \n def add_versioning_behavior(self, fti):\n@@ -94,7 +89,7 @@ def add_versioning_behavior(self, fti):\n if self.behavior_name not in behaviors:\n behaviors.append(self.behavior_name)\n # locking must be turned on for versioning support on the type\n- locking = \'plone.locking\'\n+ locking = "plone.locking"\n if locking not in behaviors:\n behaviors.append(locking)\n \n@@ -110,40 +105,37 @@ def remove_versioning_behavior(self, fti):\n fti.behaviors = behaviors\n \n def __call__(self):\n- """Perform the update and redirect if necessary, or render the page\n- """\n+ """Perform the update and redirect if necessary, or render the page"""\n postback = True\n context = aq_inner(self.context)\n \n form = self.request.form\n- submitted = form.get(\'form.submitted\', False)\n- save_button = form.get(\'form.button.Save\', None) is not None\n- cancel_button = form.get(\'form.button.Cancel\', None) is not None\n- type_id = form.get(\'old_type_id\', None)\n+ submitted = form.get("form.submitted", False)\n+ save_button = form.get("form.button.Save", None) is not None\n+ cancel_button = form.get("form.button.Cancel", None) is not None\n+ type_id = form.get("old_type_id", None)\n \n if save_button and submitted and not cancel_button:\n if type_id:\n- portal_types = getToolByName(self.context, \'portal_types\')\n- portal_repository = getToolByName(self.context,\n- \'portal_repository\')\n+ portal_types = getToolByName(self.context, "portal_types")\n+ portal_repository = getToolByName(self.context, "portal_repository")\n \n fti = getattr(portal_types, type_id)\n \n # Set FTI properties\n \n- addable = form.get(\'addable\', False)\n- allow_discussion = form.get(\'allow_discussion\', False)\n+ addable = form.get("addable", False)\n+ allow_discussion = form.get("allow_discussion", False)\n \n fti.manage_changeProperties(\n- global_allow=bool(addable),\n- allow_discussion=bool(allow_discussion)\n+ global_allow=bool(addable), allow_discussion=bool(allow_discussion)\n )\n \n- version_policy = form.get(\'versionpolicy\', "off")\n+ version_policy = form.get("versionpolicy", "off")\n if version_policy != self.current_versioning_policy():\n newpolicy = [\n- p for p in VERSION_POLICIES\n- if p["id"] == version_policy][0]\n+ p for p in VERSION_POLICIES if p["id"] == version_policy\n+ ][0]\n \n versionable_types = list(\n portal_repository.getVersionableContentTypes()\n@@ -163,25 +155,20 @@ def __call__(self):\n policy_id = policy.getId()\n if policy_id in newpolicy["policy"]:\n portal_repository.addPolicyForContentType(\n- type_id,\n- policy_id\n+ type_id, policy_id\n )\n else:\n portal_repository.removePolicyFromContentType(\n- type_id,\n- policy_id\n+ type_id, policy_id\n )\n \n- portal_repository.setVersionableContentTypes(\n- versionable_types\n- )\n+ portal_repository.setVersionableContentTypes(versionable_types)\n \n # Set Registry-entries\n registry = getUtility(IRegistry)\n \n- searchable = form.get(\'searchable\', False)\n- site_settings = registry.forInterface(\n- ISearchSchema, prefix="plone")\n+ searchable = form.get("searchable", False)\n+ site_settings = registry.forInterface(ISearchSchema, prefix="plone")\n blacklisted = [i for i in site_settings.types_not_searched]\n if searchable and type_id in blacklisted:\n blacklisted.remove(type_id)\n@@ -189,88 +176,86 @@ def __call__(self):\n blacklisted.append(type_id)\n site_settings.types_not_searched = tuple(blacklisted)\n \n- default_page_type = form.get(\'default_page_type\', False)\n- types_settings = registry.forInterface(\n- ITypesSchema, prefix="plone")\n+ default_page_type = form.get("default_page_type", False)\n+ types_settings = registry.forInterface(ITypesSchema, prefix="plone")\n default_page_types = [\n- safe_text(i) for i in types_settings.default_page_types]\n+ safe_text(i) for i in types_settings.default_page_types\n+ ]\n if default_page_type and type_id not in default_page_types:\n default_page_types.append(safe_text(type_id))\n elif not default_page_type and type_id in default_page_types:\n default_page_types.remove(type_id)\n types_settings.default_page_types = default_page_types\n- if type_id == \'Link\':\n- redirect_links = form.get(\'redirect_links\', False)\n+ if type_id == "Link":\n+ redirect_links = form.get("redirect_links", False)\n types_settings.redirect_links = redirect_links\n \n # Update workflow\n- if self.have_new_workflow() \\\n- and form.get(\'form.workflow.submitted\', False) \\\n- and save_button:\n+ if (\n+ self.have_new_workflow()\n+ and form.get("form.workflow.submitted", False)\n+ and save_button\n+ ):\n if self.new_workflow_is_different():\n new_wf = self.new_workflow()\n- if new_wf == \'[none]\':\n+ if new_wf == "[none]":\n chain = ()\n- elif new_wf == \'(Default)\':\n+ elif new_wf == "(Default)":\n chain = new_wf\n else:\n chain = (new_wf,)\n state_map = {\n- s[\'old_state\']: s[\'new_state\']\n- for s in form.get(\'new_wfstates\', [])\n+ s["old_state"]: s["new_state"]\n+ for s in form.get("new_wfstates", [])\n }\n- if \'[none]\' in state_map:\n- state_map[None] = state_map[\'[none]\']\n- del state_map[\'[none]\']\n+ if "[none]" in state_map:\n+ state_map[None] = state_map["[none]"]\n+ del state_map["[none]"]\n if type_id:\n type_ids = (type_id,)\n else:\n- wt = getToolByName(self.context, \'portal_workflow\')\n- tt = getToolByName(self.context, \'portal_types\')\n- nondefault = [\n- info[0] for info in wt.listChainOverrides()\n- ]\n+ wt = getToolByName(self.context, "portal_workflow")\n+ tt = getToolByName(self.context, "portal_types")\n+ nondefault = [info[0] for info in wt.listChainOverrides()]\n type_ids = [\n- type for type in tt.listContentTypes()\n+ type\n+ for type in tt.listContentTypes()\n if type not in nondefault\n ]\n- wt.setChainForPortalTypes(\n- type_ids,\n- wt.getDefaultChain()\n- )\n- wt.setDefaultChain(\',\'.join(chain))\n- chain = \'(Default)\'\n+ wt.setChainForPortalTypes(type_ids, wt.getDefaultChain())\n+ wt.setDefaultChain(",".join(chain))\n+ chain = "(Default)"\n \n- remap_workflow(context, type_ids=type_ids, chain=chain,\n- state_map=state_map)\n+ remap_workflow(\n+ context, type_ids=type_ids, chain=chain, state_map=state_map\n+ )\n \n- data = {\'workflow\': new_wf}\n+ data = {"workflow": new_wf}\n notify(ConfigurationChangedEvent(self, data))\n \n else:\n- portal_workflow = getToolByName(context, \'portal_workflow\')\n- if self.new_workflow() == \'(Default)\':\n+ portal_workflow = getToolByName(context, "portal_workflow")\n+ if self.new_workflow() == "(Default)":\n # The WorkflowTool API can not handle this sanely\n cbt = portal_workflow._chains_by_type\n if type_id in cbt:\n del cbt[type_id]\n else:\n portal_workflow.setChainForPortalTypes(\n- (type_id,),\n- self.new_workflow()\n+ (type_id,), self.new_workflow()\n )\n \n self.request.response.redirect(\n- \'{}/@@content-controlpanel?type_id={}\'.format(\n- context.absolute_url(),\n- type_id\n+ "{}/@@content-controlpanel?type_id={}".format(\n+ context.absolute_url(), type_id\n )\n )\n postback = False\n \n elif cancel_button:\n self.request.response.redirect(\n- self.context.absolute_url() + \'/@@overview-controlpanel\')\n+ self.context.absolute_url() + "/@@overview-controlpanel"\n+ )\n postback = False\n \n if postback:\n@@ -284,22 +269,17 @@ def versioning_policies(self):\n @memoize\n def selectable_types(self):\n vocab_factory = getUtility(\n- IVocabularyFactory,\n- name="plone.app.vocabularies.ReallyUserFriendlyTypes"\n+ IVocabularyFactory, name="plone.app.vocabularies.ReallyUserFriendlyTypes"\n )\n types = []\n for v in vocab_factory(self.context):\n if v.title:\n title = translate(v.title, context=self.request)\n else:\n- title = translate(\n- v.token,\n- domain=\'plone\',\n- context=self.request\n- )\n+ title = translate(v.token, domain="plone", context=self.request)\n types.append(dict(id=v.value, title=title))\n \n- types.sort(key=itemgetter(\'title\'))\n+ types.sort(key=itemgetter("title"))\n return types\n \n def selected_type_title(self):\n@@ -309,13 +289,13 @@ def selected_type_description(self):\n return self.fti.Description()\n \n def is_addable(self):\n- return self.fti.getProperty(\'global_allow\', False)\n+ return self.fti.getProperty("global_allow", False)\n \n def is_discussion_allowed(self):\n- return self.fti.getProperty(\'allow_discussion\', False)\n+ return self.fti.getProperty("allow_discussion", False)\n \n def current_versioning_policy(self):\n- portal_repository = getToolByName(self.context, \'portal_repository\')\n+ portal_repository = getToolByName(self.context, "portal_repository")\n if self.type_id not in portal_repository.getVersionableContentTypes():\n return "off"\n policy = set(portal_repository.getPolicyMap().get(self.type_id, ()))\n@@ -328,7 +308,7 @@ def is_searchable(self):\n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISearchSchema, prefix="plone")\n blacklisted = settings.types_not_searched\n- return (self.type_id not in blacklisted)\n+ return self.type_id not in blacklisted\n \n def is_default_page_type(self):\n registry = getUtility(IRegistry)\n@@ -336,7 +316,7 @@ def is_default_page_type(self):\n return self.type_id in settings.default_page_types\n \n def is_redirect_links_enabled(self):\n- if self.type_id == \'Link\':\n+ if self.type_id == "Link":\n registry = getUtility(IRegistry)\n settings = registry.forInterface(ITypesSchema, prefix="plone")\n return settings.redirect_links\n@@ -345,19 +325,21 @@ def is_redirect_links_enabled(self):\n @memoize\n def current_workflow(self):\n context = aq_inner(self.context)\n- portal_workflow = getToolByName(context, \'portal_workflow\')\n+ portal_workflow = getToolByName(context, "portal_workflow")\n default_workflow = self.default_workflow(False)\n nondefault = [info[0] for info in portal_workflow.listChainOverrides()]\n chain = portal_workflow.getChainForPortalType(self.type_id)\n empty_workflow_dict = dict(\n- id=\'[none]\',\n+ id="[none]",\n title=_("label_no_workflow"),\n- description=[_(\n- "description_no_workflow",\n- default="This type has no workflow. The visibilty "\n- "of items of this type is determined by "\n- "the folder they are in.")\n- ]\n+ description=[\n+ _(\n+ "description_no_workflow",\n+ default="This type has no workflow. The visibilty "\n+ "of items of this type is determined by "\n+ "the folder they are in.",\n+ )\n+ ],\n )\n \n if self.type_id in nondefault:\n@@ -365,105 +347,96 @@ def current_workflow(self):\n wf_id = chain[0]\n wf = getattr(portal_workflow, wf_id)\n title = translate(\n- safe_text(wf.title),\n- domain=\'plone\',\n- context=self.request\n+ safe_text(wf.title), domain="plone", context=self.request\n )\n return dict(\n id=wf.id,\n title=title,\n description=format_description(\n- safe_text(wf.description),\n- self.request\n- )\n+ safe_text(wf.description), self.request\n+ ),\n )\n else:\n return empty_workflow_dict\n \n- if default_workflow == \'[none]\':\n+ if default_workflow == "[none]":\n return empty_workflow_dict\n \n default_title = translate(\n- safe_text(default_workflow.title),\n- domain=\'plone\',\n- context=self.request\n+ safe_text(default_workflow.title), domain="plone", context=self.request\n+ )\n+ return dict(\n+ id="(Default)",\n+ title=_(\n+ "label_default_workflow_title",\n+ default="Default workflow (${title})",\n+ mapping=dict(title=default_title),\n+ ),\n+ description=format_description(default_workflow.description, self.request),\n )\n- return dict(id=\'(Default)\',\n- title=_(\n- "label_default_workflow_title",\n- default="Default workflow (${title})",\n- mapping=dict(title=default_title)),\n- description=format_description(\n- default_workflow.description,\n- self.request)\n- )\n \n def available_workflows(self):\n- vocab_factory = getUtility(IVocabularyFactory,\n- name="plone.app.vocabularies.Workflows")\n+ vocab_factory = getUtility(\n+ IVocabularyFactory, name="plone.app.vocabularies.Workflows"\n+ )\n workflows = []\n for v in vocab_factory(self.context):\n if v.title:\n title = translate(v.title, context=self.request)\n else:\n- title = translate(\n- v.token,\n- domain=\'plone\',\n- context=self.request\n- )\n+ title = translate(v.token, domain="plone", context=self.request)\n workflows.append(dict(id=v.value, title=title))\n \n- workflows.sort(key=itemgetter(\'title\'))\n+ workflows.sort(key=itemgetter("title"))\n \n default_workflow = self.default_workflow(False)\n- if self.type_id and default_workflow != \'[none]\':\n+ if self.type_id and default_workflow != "[none]":\n # Only offer a default workflow option on a real type\n default_workflow = self.default_workflow(False)\n default_title = translate(\n- safe_text(default_workflow.title),\n- domain=\'plone\',\n- context=self.request\n+ safe_text(default_workflow.title), domain="plone", context=self.request\n )\n workflows.insert(\n 0,\n dict(\n- id=\'(Default)\',\n- title=_("label_default_workflow_title",\n- default="Default workflow (${title})",\n- mapping=dict(title=default_title)),\n+ id="(Default)",\n+ title=_(\n+ "label_default_workflow_title",\n+ default="Default workflow (${title})",\n+ mapping=dict(title=default_title),\n+ ),\n description=format_description(\n- default_workflow.description,\n- self.request\n- )\n- )\n+ default_workflow.description, self.request\n+ ),\n+ ),\n )\n \n return workflows\n \n @memoize\n def new_workflow(self):\n- current_workflow = self.current_workflow()[\'id\']\n- if self.type_id == \'\':\n+ current_workflow = self.current_workflow()["id"]\n+ if self.type_id == "":\n # If we are looking at the default workflow we need to show\n # the real workflow\n current_workflow = self.real_workflow(current_workflow)\n- old_type_id = self.request.form.get(\'old_type_id\', self.type_id)\n+ old_type_id = self.request.form.get("old_type_id", self.type_id)\n if old_type_id != self.type_id:\n return current_workflow\n else:\n- return self.request.form.get(\'new_workflow\', current_workflow)\n+ return self.request.form.get("new_workflow", current_workflow)\n \n @memoize\n def have_new_workflow(self):\n- return self.current_workflow()[\'id\'] != self.new_workflow()\n+ return self.current_workflow()["id"] != self.new_workflow()\n \n @memoize\n def default_workflow(self, id_only=True):\n- portal_workflow = getToolByName(self.context, \'portal_workflow\')\n+ portal_workflow = getToolByName(self.context, "portal_workflow")\n default_chain = portal_workflow.getDefaultChain()\n if not default_chain:\n # There is no default workflow\n- return \'[none]\'\n+ return "[none]"\n id = default_chain[0]\n if id_only:\n return id\n@@ -472,7 +445,7 @@ def default_workflow(self, id_only=True):\n \n @memoize\n def real_workflow(self, wf):\n- if wf == \'(Default)\':\n+ if wf == "(Default)":\n return self.default_workflow()\n else:\n return wf\n@@ -480,26 +453,28 @@ def real_workflow(self, wf):\n @memoize\n def new_workflow_is_different(self):\n new_workflow = self.new_workflow()\n- current_workflow = self.current_workflow()[\'id\']\n+ current_workflow = self.current_workflow()["id"]\n \n- return self.real_workflow(new_workflow) != self.real_workflow(\n- current_workflow)\n+ return self.real_workflow(new_workflow) != self.real_workflow(current_workflow)\n \n @memoize\n def new_workflow_is_none(self):\n- return self.new_workflow() == \'[none]\'\n+ return self.new_workflow() == "[none]"\n \n def new_workflow_description(self):\n- portal_workflow = getToolByName(self.context, \'portal_workflow\')\n+ portal_workflow = getToolByName(self.context, "portal_workflow")\n new_workflow = self.new_workflow()\n \n if self.new_workflow_is_different():\n if self.new_workflow_is_none():\n- return [_(\n- "description_no_workflow",\n- default="This type has no workflow. The visibilty of "\n- "items of this type is determined by the "\n- "folder they are in.")]\n+ return [\n+ _(\n+ "description_no_workflow",\n+ default="This type has no workflow. The visibilty of "\n+ "items of this type is determined by the "\n+ "folder they are in.",\n+ )\n+ ]\n new_workflow = self.real_workflow(self.new_workflow())\n wf = getattr(portal_workflow, new_workflow)\n return format_description(wf.description, self.request)\n@@ -509,32 +484,32 @@ def new_workflow_description(self):\n def new_workflow_available_states(self):\n if self.new_workflow_is_different():\n new_workflow = self.real_workflow(self.new_workflow())\n- portal_workflow = getToolByName(self.context, \'portal_workflow\')\n+ portal_workflow = getToolByName(self.context, "portal_workflow")\n wf = getattr(portal_workflow, new_workflow)\n states = []\n for s in wf.states.objectValues():\n- title = translate(\n- s.title,\n- domain=\'plone\',\n- context=self.request\n- )\n+ title = translate(s.title, domain="plone", context=self.request)\n states.append(dict(id=s.id, title=title))\n return states\n else:\n return []\n \n def suggested_state_map(self):\n- current_workflow = self.real_workflow(self.current_workflow()[\'id\'])\n+ current_workflow = self.real_workflow(self.current_workflow()["id"])\n new_workflow = self.real_workflow(self.new_workflow())\n \n- portal_workflow = getToolByName(self.context, \'portal_workflow\')\n+ portal_workflow = getToolByName(self.context, "portal_workflow")\n \n- if current_workflow == \'[none]\':\n+ if current_workflow == "[none]":\n new_wf = getattr(portal_workflow, new_workflow)\n default_state = new_wf.initial_state\n- return [dict(old_id=\'[none]\',\n- old_title=_("No workflow"),\n- suggested_id=default_state)]\n+ return [\n+ dict(\n+ old_id="[none]",\n+ old_title=_("No workflow"),\n+ suggested_id=default_state,\n+ )\n+ ]\n \n elif self.new_workflow_is_different():\n old_wf = getattr(portal_workflow, current_workflow)\n@@ -545,16 +520,14 @@ def suggested_state_map(self):\n \n states = []\n for old in old_wf.states.objectValues():\n- title = translate(\n- old.title,\n- domain=\'plone\',\n- context=self.request\n+ title = translate(old.title, domain="plone", context=self.request)\n+ states.append(\n+ dict(\n+ old_id=old.id,\n+ old_title=title,\n+ suggested_id=(old.id in new_states and old.id or default_state),\n+ )\n )\n- states.append(dict(\n- old_id=old.id,\n- old_title=title,\n- suggested_id=(old.id in new_states and\n- old.id or default_state)))\n return states\n else:\n return []\ndiff --git a/Products/CMFPlone/controlpanel/browser/usergroups.py b/Products/CMFPlone/controlpanel/browser/usergroups.py\nindex 330194ac64..446cc3ccf4 100644\n--- a/Products/CMFPlone/controlpanel/browser/usergroups.py\n+++ b/Products/CMFPlone/controlpanel/browser/usergroups.py\n@@ -25,14 +25,14 @@ class UserGroupsSettingsControlPanel(AutoExtensibleForm, form.EditForm):\n form_name = _("User/Groups settings")\n control_panel_view = "usergroups-controlpanel"\n \n- @button.buttonAndHandler(_(\'label_save\', default="Save"), name=\'save\')\n+ @button.buttonAndHandler(_("label_save", default="Save"), name="save")\n def handleApply(self, action):\n super().handleApply(self, action)\n \n def updateActions(self):\n super().updateActions()\n- if self.actions and \'save\' in self.actions:\n- self.actions[\'save\'].addClass(\'btn-primary\')\n+ if self.actions and "save" in self.actions:\n+ self.actions["save"].addClass("btn-primary")\n \n \n class ControlPanelFormWrapper(layout.FormWrapper):\n@@ -40,7 +40,7 @@ class ControlPanelFormWrapper(layout.FormWrapper):\n panel layout.\n """\n \n- index = ViewPageTemplateFile(\'controlpanel_usergroups_layout.pt\')\n+ index = ViewPageTemplateFile("controlpanel_usergroups_layout.pt")\n \n \n UserGroupsSettingsPanelView = layout.wrap_form(\n@@ -49,11 +49,10 @@ class ControlPanelFormWrapper(layout.FormWrapper):\n \n \n class UsersGroupsControlPanelView(BrowserView):\n-\n @property\n def portal_roles(self):\n- pmemb = getToolByName(aq_inner(self.context), \'portal_membership\')\n- return [r for r in pmemb.getPortalRoles() if r != \'Owner\']\n+ pmemb = getToolByName(aq_inner(self.context), "portal_membership")\n+ return [r for r in pmemb.getPortalRoles() if r != "Owner"]\n \n @property\n def many_users(self):\n@@ -65,37 +64,67 @@ def many_groups(self):\n \n @property\n def email_as_username(self):\n- return getAdapter(aq_inner(self.context), ISecuritySchema).get_use_email_as_login()\n+ return getAdapter(\n+ aq_inner(self.context), ISecuritySchema\n+ ).get_use_email_as_login()\n \n def makeQuery(self, **kw):\n return make_query(**kw)\n \n- def membershipSearch(self, searchString=\'\', searchUsers=True, searchGroups=True, ignore=[]):\n+ def membershipSearch(\n+ self, searchString="", searchUsers=True, searchGroups=True, ignore=[]\n+ ):\n """Search for users and/or groups, returning actual member and group items\n- Replaces the now-deprecated prefs_user_groups_search.py script"""\n+ Replaces the now-deprecated prefs_user_groups_search.py script"""\n groupResults = userResults = []\n \n- gtool = getToolByName(self, \'portal_groups\')\n- mtool = getToolByName(self, \'portal_membership\')\n+ gtool = getToolByName(self, "portal_groups")\n+ mtool = getToolByName(self, "portal_membership")\n \n searchView = getMultiAdapter(\n- (aq_inner(self.context), self.request), name=\'pas_search\')\n+ (aq_inner(self.context), self.request), name="pas_search"\n+ )\n \n if searchGroups:\n- groupResults = searchView.merge(chain(\n- *[searchView.searchGroups(**{field: searchString}) for field in [\'id\', \'title\']]), \'groupid\')\n- groupResults = [gtool.getGroupById(g[\'id\']) for g in groupResults if g[\n- \'id\'] not in ignore]\n- groupResults.sort(key=lambda x: x is not None and normalizeString(\n- x.getGroupTitleOrName()))\n+ groupResults = searchView.merge(\n+ chain(\n+ *[\n+ searchView.searchGroups(**{field: searchString})\n+ for field in ["id", "title"]\n+ ]\n+ ),\n+ "groupid",\n+ )\n+ groupResults = [\n+ gtool.getGroupById(g["id"])\n+ for g in groupResults\n+ if g["id"] not in ignore\n+ ]\n+ groupResults.sort(\n+ key=lambda x: x is not None and normalizeString(x.getGroupTitleOrName())\n+ )\n \n if searchUsers:\n- userResults = searchView.merge(chain(*[searchView.searchUsers(\n- **{field: searchString}) for field in [\'login\', \'fullname\', \'email\']]), \'userid\')\n- userResults = [mtool.getMemberById(u[\'id\']) for u in userResults if u[\n- \'id\'] not in ignore]\n- userResults.sort(key=lambda x: x is not None and x.getProperty(\n- \'fullname\') is not None and normalizeString(x.getProperty(\'fullname\')) or \'\')\n+ userResults = searchView.merge(\n+ chain(\n+ *[\n+ searchView.searchUsers(**{field: searchString})\n+ for field in ["login", "fullname", "email"]\n+ ]\n+ ),\n+ "userid",\n+ )\n+ userResults = [\n+ mtool.getMemberById(u["id"])\n+ for u in userResults\n+ if u["id"] not in ignore\n+ ]\n+ userResults.sort(\n+ key=lambda x: x is not None\n+ and x.getProperty("fullname") is not None\n+ and normalizeString(x.getProperty("fullname"))\n+ or ""\n+ )\n \n return groupResults + userResults\n \n@@ -128,7 +157,7 @@ def is_zope_manager(self):\n @property\n def show_group_listing_warning(self):\n if not self.searchString:\n- acl = getToolByName(self, \'acl_users\')\n+ acl = getToolByName(self, "acl_users")\n if acl.canListAllGroups():\n if self.many_groups:\n return True\n@@ -137,7 +166,7 @@ def show_group_listing_warning(self):\n @property\n def show_users_listing_warning(self):\n if not self.searchString:\n- acl = getToolByName(self, \'acl_users\')\n+ acl = getToolByName(self, "acl_users")\n # XXX Huh? Is canListAllUsers broken?\n if not acl.canListAllUsers():\n if self.many_users:\ndiff --git a/Products/CMFPlone/controlpanel/browser/usergroups_groupdetails.py b/Products/CMFPlone/controlpanel/browser/usergroups_groupdetails.py\nindex 53d6591743..70216f6c31 100644\n--- a/Products/CMFPlone/controlpanel/browser/usergroups_groupdetails.py\n+++ b/Products/CMFPlone/controlpanel/browser/usergroups_groupdetails.py\n@@ -9,7 +9,6 @@\n \n \n class GroupDetailsControlPanel(UsersGroupsControlPanelView):\n-\n def get_group_property(self, prop_id):\n try:\n return self.group.getProperty(prop_id, None)\n@@ -19,61 +18,69 @@ def get_group_property(self, prop_id):\n def __call__(self):\n context = aq_inner(self.context)\n \n- self.gtool = getToolByName(context, \'portal_groups\')\n- self.gdtool = getToolByName(context, \'portal_groupdata\')\n- self.regtool = getToolByName(context, \'portal_registration\')\n- self.groupname = getattr(self.request, \'groupname\', None)\n- self.grouproles = self.request.set(\'grouproles\', [])\n+ self.gtool = getToolByName(context, "portal_groups")\n+ self.gdtool = getToolByName(context, "portal_groupdata")\n+ self.regtool = getToolByName(context, "portal_registration")\n+ self.groupname = getattr(self.request, "groupname", None)\n+ self.grouproles = self.request.set("grouproles", [])\n self.group = self.gtool.getGroupById(self.groupname)\n self.grouptitle = self.groupname\n if self.group is not None:\n self.grouptitle = self.group.getGroupTitleOrName()\n \n- self.request.set(\'grouproles\', self.group.getRoles()\n- if self.group else [])\n+ self.request.set("grouproles", self.group.getRoles() if self.group else [])\n \n- submitted = self.request.form.get(\'form.submitted\', False)\n+ submitted = self.request.form.get("form.submitted", False)\n if submitted:\n CheckAuthenticator(self.request)\n \n- msg = _(\'No changes made.\')\n+ msg = _("No changes made.")\n self.group = None\n \n- title = self.request.form.get(\'title\', None)\n- description = self.request.form.get(\'description\', None)\n- addname = self.request.form.get(\'addname\', None)\n+ title = self.request.form.get("title", None)\n+ description = self.request.form.get("description", None)\n+ addname = self.request.form.get("addname", None)\n \n if addname:\n if not self.regtool.isMemberIdAllowed(addname):\n- msg = _(\'The group name you entered is not valid.\')\n- IStatusMessage(self.request).add(msg, \'error\')\n+ msg = _("The group name you entered is not valid.")\n+ IStatusMessage(self.request).add(msg, "error")\n return self.index()\n \n- success = self.gtool.addGroup(addname, (), (), title=title,\n- description=description,\n- REQUEST=self.request)\n+ success = self.gtool.addGroup(\n+ addname,\n+ (),\n+ (),\n+ title=title,\n+ description=description,\n+ REQUEST=self.request,\n+ )\n if not success:\n msg = _(\n- \'Could not add group ${name}, perhaps a user or \'\n- \'group with this name already exists.\',\n- mapping={\'name\': addname}\n+ "Could not add group ${name}, perhaps a user or "\n+ "group with this name already exists.",\n+ mapping={"name": addname},\n )\n- IStatusMessage(self.request).add(msg, \'error\')\n+ IStatusMessage(self.request).add(msg, "error")\n return self.index()\n \n self.group = self.gtool.getGroupById(addname)\n- msg = _(\'Group ${name} has been added.\',\n- mapping={\'name\': addname})\n+ msg = _("Group ${name} has been added.", mapping={"name": addname})\n \n elif self.groupname:\n- self.gtool.editGroup(self.groupname, roles=None, groups=None,\n- title=title, description=description,\n- REQUEST=context.REQUEST)\n+ self.gtool.editGroup(\n+ self.groupname,\n+ roles=None,\n+ groups=None,\n+ title=title,\n+ description=description,\n+ REQUEST=context.REQUEST,\n+ )\n self.group = self.gtool.getGroupById(self.groupname)\n- msg = _(\'Changes saved.\')\n+ msg = _("Changes saved.")\n \n else:\n- msg = _(\'Group name required.\')\n+ msg = _("Group name required.")\n \n processed = {}\n for id, property in self.gdtool.propertyItems():\n@@ -84,12 +91,12 @@ def __call__(self):\n # exist\n self.group.setGroupProperties(processed)\n \n- IStatusMessage(self.request).add(\n- msg, type=self.group and \'info\' or \'error\')\n+ IStatusMessage(self.request).add(msg, type=self.group and "info" or "error")\n if self.group and not self.groupname:\n- target_url = \'{}/{}\'.format(self.context.absolute_url(),\n- \'@@usergroup-groupprefs\')\n+ target_url = "{}/{}".format(\n+ self.context.absolute_url(), "@@usergroup-groupprefs"\n+ )\n self.request.response.redirect(target_url)\n- return \'\'\n+ return ""\n \n return self.index()\ndiff --git a/Products/CMFPlone/controlpanel/browser/usergroups_groupmembership.py b/Products/CMFPlone/controlpanel/browser/usergroups_groupmembership.py\nindex 2cd097703d..27b817a144 100644\n--- a/Products/CMFPlone/controlpanel/browser/usergroups_groupmembership.py\n+++ b/Products/CMFPlone/controlpanel/browser/usergroups_groupmembership.py\n@@ -8,72 +8,64 @@\n \n \n class GroupMembershipControlPanel(UsersGroupsControlPanelView):\n-\n def update(self):\n- self.groupname = getattr(self.request, \'groupname\')\n- self.gtool = getToolByName(self, \'portal_groups\')\n- self.mtool = getToolByName(self, \'portal_membership\')\n+ self.groupname = getattr(self.request, "groupname")\n+ self.gtool = getToolByName(self, "portal_groups")\n+ self.mtool = getToolByName(self, "portal_membership")\n self.group = self.gtool.getGroupById(self.groupname)\n if self.group is None:\n return\n \n self.grouptitle = self.group.getGroupTitleOrName() or self.groupname\n \n- self.request.set(\'grouproles\', self.group.getRoles()\n- if self.group else [])\n+ self.request.set("grouproles", self.group.getRoles() if self.group else [])\n self.canAddUsers = True\n- if \'Manager\' in self.request.get(\'grouproles\') and not self.is_zope_manager:\n+ if "Manager" in self.request.get("grouproles") and not self.is_zope_manager:\n self.canAddUsers = False\n \n self.groupquery = self.makeQuery(groupname=self.groupname)\n self.groupkeyquery = self.makeQuery(key=self.groupname)\n \n form = self.request.form\n- submitted = form.get(\'form.submitted\', False)\n+ submitted = form.get("form.submitted", False)\n \n self.searchResults = []\n- self.searchString = \'\'\n+ self.searchString = ""\n self.newSearch = False\n \n if submitted:\n # add/delete before we search so we don\'t show stale results\n- toAdd = form.get(\'add\', [])\n+ toAdd = form.get("add", [])\n if toAdd:\n if not self.canAddUsers:\n raise Forbidden\n \n for u in toAdd:\n- self.gtool.addPrincipalToGroup(\n- u, self.groupname, self.request)\n- self.context.plone_utils.addPortalMessage(_(\'Changes made.\'))\n+ self.gtool.addPrincipalToGroup(u, self.groupname, self.request)\n+ self.context.plone_utils.addPortalMessage(_("Changes made."))\n \n- toDelete = form.get(\'delete\', [])\n+ toDelete = form.get("delete", [])\n if toDelete:\n for u in toDelete:\n- self.gtool.removePrincipalFromGroup(\n- u, self.groupname, self.request)\n- self.context.plone_utils.addPortalMessage(_(\'Changes made.\'))\n+ self.gtool.removePrincipalFromGroup(u, self.groupname, self.request)\n+ self.context.plone_utils.addPortalMessage(_("Changes made."))\n \n- search = form.get(\'form.button.Search\', None) is not None\n- edit = form.get(\'form.button.Edit\', None) is not None and toDelete\n- add = form.get(\'form.button.Add\', None) is not None and toAdd\n+ search = form.get("form.button.Search", None) is not None\n+ edit = form.get("form.button.Edit", None) is not None and toDelete\n+ add = form.get("form.button.Add", None) is not None and toAdd\n isBatched = form.get("b_start", None) is not None\n findAll = (\n- form.get(\'form.button.FindAll\', None) is not None\n- and not self.many_users\n- )\n- unbatchedAll = (\n- form.get("showAll", "") == "y"\n+ form.get("form.button.FindAll", None) is not None\n and not self.many_users\n )\n+ unbatchedAll = form.get("showAll", "") == "y" and not self.many_users\n # The search string should be cleared when one of the\n # non-search buttons has been clicked.\n if findAll or unbatchedAll or edit or add:\n- form[\'searchstring\'] = \'\'\n- self.searchString = form.get(\'searchstring\', \'\')\n+ form["searchstring"] = ""\n+ self.searchString = form.get("searchstring", "")\n if findAll or isBatched or unbatchedAll or bool(self.searchString):\n- self.searchResults = self.getPotentialMembers(\n- self.searchString)\n+ self.searchResults = self.getPotentialMembers(self.searchString)\n \n if search or findAll:\n self.newSearch = True\n@@ -102,11 +94,17 @@ def getMembers(self):\n userResults.append(principal)\n \n groupResults.sort(key=lambda x: normalizeString(x.getGroupTitleOrName()))\n- userResults.sort(key=lambda x: normalizeString(x.getProperty(\'fullname\') or \'\'))\n+ userResults.sort(key=lambda x: normalizeString(x.getProperty("fullname") or ""))\n \n return groupResults + userResults\n \n def getPotentialMembers(self, searchString):\n ignoredUsersGroups = [\n- x.id for x in self.getMembers() + [self.group, ] if x is not None]\n+ x.id\n+ for x in self.getMembers()\n+ + [\n+ self.group,\n+ ]\n+ if x is not None\n+ ]\n return self.membershipSearch(searchString, ignore=ignoredUsersGroups)\ndiff --git a/Products/CMFPlone/controlpanel/browser/usergroups_groupsoverview.py b/Products/CMFPlone/controlpanel/browser/usergroups_groupsoverview.py\nindex 532050ffdd..4dad8f81bf 100644\n--- a/Products/CMFPlone/controlpanel/browser/usergroups_groupsoverview.py\n+++ b/Products/CMFPlone/controlpanel/browser/usergroups_groupsoverview.py\n@@ -12,13 +12,12 @@\n \n \n class GroupsOverviewControlPanel(UsersGroupsControlPanelView):\n-\n def __call__(self):\n form = self.request.form\n- submitted = form.get(\'form.submitted\', False)\n- search = form.get(\'form.button.Search\', None) is not None\n- findAll = form.get(\'form.button.FindAll\', None) is not None\n- self.searchString = not findAll and form.get(\'searchstring\', \'\') or \'\'\n+ submitted = form.get("form.submitted", False)\n+ search = form.get("form.button.Search", None) is not None\n+ findAll = form.get("form.button.FindAll", None) is not None\n+ self.searchString = not findAll and form.get("searchstring", "") or ""\n self.searchResults = []\n self.newSearch = False\n \n@@ -26,37 +25,50 @@ def __call__(self):\n self.newSearch = True\n \n if submitted:\n- if form.get(\'form.button.Modify\', None) is not None:\n- self.manageGroup([group[len(\'group_\'):] for group in self.request.keys() if group.startswith(\'group_\')],\n- form.get(\'delete\', []))\n+ if form.get("form.button.Modify", None) is not None:\n+ self.manageGroup(\n+ [\n+ group[len("group_") :]\n+ for group in self.request.keys()\n+ if group.startswith("group_")\n+ ],\n+ form.get("delete", []),\n+ )\n \n # Only search for all (\'\') if the many_users flag is not set.\n- if not(self.many_groups) or bool(self.searchString):\n+ if not (self.many_groups) or bool(self.searchString):\n self.searchResults = self.doSearch(self.searchString)\n \n return self.index()\n \n def doSearch(self, searchString):\n- """ Search for a group by id or title"""\n- acl = getToolByName(self, \'acl_users\')\n+ """Search for a group by id or title"""\n+ acl = getToolByName(self, "acl_users")\n rolemakers = acl.plugins.listPlugins(IRolesPlugin)\n \n searchView = getMultiAdapter(\n- (aq_inner(self.context), self.request), name=\'pas_search\')\n+ (aq_inner(self.context), self.request), name="pas_search"\n+ )\n \n # First, search for inherited roles assigned to each group.\n # We push this in the request so that IRoles plugins are told provide\n # the roles inherited from the groups to which the principal belongs.\n- self.request.set(\'__ignore_group_roles__\', False)\n- self.request.set(\'__ignore_direct_roles__\', True)\n- inheritance_enabled_groups = searchView.merge(chain(\n- *[searchView.searchGroups(**{field: searchString}) for field in [\'id\', \'title\']]), \'id\')\n+ self.request.set("__ignore_group_roles__", False)\n+ self.request.set("__ignore_direct_roles__", True)\n+ inheritance_enabled_groups = searchView.merge(\n+ chain(\n+ *[\n+ searchView.searchGroups(**{field: searchString})\n+ for field in ["id", "title"]\n+ ]\n+ ),\n+ "id",\n+ )\n allInheritedRoles = {}\n for group_info in inheritance_enabled_groups:\n- groupId = group_info[\'id\']\n+ groupId = group_info["id"]\n group = acl.getGroupById(groupId)\n- group_info[\'title\'] = group.getProperty(\n- \'title\', group_info[\'title\'])\n+ group_info["title"] = group.getProperty("title", group_info["title"])\n allAssignedRoles = []\n for rolemaker_id, rolemaker in rolemakers:\n # getRolesForPrincipal can return None\n@@ -67,20 +79,26 @@ def doSearch(self, searchString):\n # Now, search for all roles explicitly assigned to each group.\n # We push this in the request so that IRoles plugins don\'t provide\n # the roles inherited from the groups to which the principal belongs.\n- self.request.set(\'__ignore_group_roles__\', True)\n- self.request.set(\'__ignore_direct_roles__\', False)\n- explicit_groups = searchView.merge(chain(\n- *[searchView.searchGroups(**{field: searchString}) for field in [\'id\', \'title\']]), \'id\')\n+ self.request.set("__ignore_group_roles__", True)\n+ self.request.set("__ignore_direct_roles__", False)\n+ explicit_groups = searchView.merge(\n+ chain(\n+ *[\n+ searchView.searchGroups(**{field: searchString})\n+ for field in ["id", "title"]\n+ ]\n+ ),\n+ "id",\n+ )\n \n # Tack on some extra data, including whether each role is explicitly\n # assigned (\'explicit\'), inherited (\'inherited\'), or not assigned at\n # all (None).\n results = []\n for group_info in explicit_groups:\n- groupId = group_info[\'id\']\n+ groupId = group_info["id"]\n group = acl.getGroupById(groupId)\n- group_info[\'title\'] = group.getProperty(\n- \'title\', group_info[\'title\'])\n+ group_info["title"] = group.getProperty("title", group_info["title"])\n \n explicitlyAssignedRoles = []\n for rolemaker_id, rolemaker in rolemakers:\n@@ -91,26 +109,30 @@ def doSearch(self, searchString):\n roleList = {}\n for role in self.portal_roles:\n canAssign = group.canAssignRole(role)\n- if role == \'Manager\' and not self.is_zope_manager:\n+ if role == "Manager" and not self.is_zope_manager:\n canAssign = False\n- roleList[role] = {\'canAssign\': canAssign,\n- \'explicit\': role in explicitlyAssignedRoles,\n- \'inherited\': role in allInheritedRoles.get(groupId, [])}\n+ roleList[role] = {\n+ "canAssign": canAssign,\n+ "explicit": role in explicitlyAssignedRoles,\n+ "inherited": role in allInheritedRoles.get(groupId, []),\n+ }\n \n canDelete = group.canDelete()\n- if (\'Manager\' in explicitlyAssignedRoles or\n- \'Manager\' in allInheritedRoles.get(groupId, [])):\n+ if (\n+ "Manager" in explicitlyAssignedRoles\n+ or "Manager" in allInheritedRoles.get(groupId, [])\n+ ):\n if not self.is_zope_manager:\n canDelete = False\n \n- group_info[\'roles\'] = roleList\n- group_info[\'can_delete\'] = canDelete\n+ group_info["roles"] = roleList\n+ group_info["can_delete"] = canDelete\n results.append(group_info)\n # Sort the groups by title\n- sortedResults = searchView.sort(results, \'title\')\n+ sortedResults = searchView.sort(results, "title")\n \n # Reset the request variable, just in case.\n- self.request.set(\'__ignore_group_roles__\', False)\n+ self.request.set("__ignore_group_roles__", False)\n return sortedResults\n \n def manageGroup(self, groups=None, delete=None):\n@@ -122,30 +144,30 @@ def manageGroup(self, groups=None, delete=None):\n context = aq_inner(self.context)\n \n groupstool = context.portal_groups\n- utils = getToolByName(context, \'plone_utils\')\n- groupstool = getToolByName(context, \'portal_groups\')\n+ utils = getToolByName(context, "plone_utils")\n+ groupstool = getToolByName(context, "portal_groups")\n \n- message = _(\'No changes made.\')\n+ message = _("No changes made.")\n \n for group in groups:\n- roles = [r for r in self.request.form[\'group_\' + group] if r]\n+ roles = [r for r in self.request.form["group_" + group] if r]\n group_obj = groupstool.getGroupById(group)\n current_roles = group_obj.getRoles()\n if not self.is_zope_manager:\n # don\'t allow adding or removing the Manager role\n- if (\'Manager\' in roles) != (\'Manager\' in current_roles):\n+ if ("Manager" in roles) != ("Manager" in current_roles):\n raise Forbidden\n \n groupstool.editGroup(group, roles=roles, groups=())\n- message = _(\'Changes saved.\')\n+ message = _("Changes saved.")\n \n if delete:\n for group_id in delete:\n group = groupstool.getGroupById(group_id)\n- if \'Manager\' in group.getRoles() and not self.is_zope_manager:\n+ if "Manager" in group.getRoles() and not self.is_zope_manager:\n raise Forbidden\n \n groupstool.removeGroups(delete)\n- message = _(\'Group(s) deleted.\')\n+ message = _("Group(s) deleted.")\n \n utils.addPortalMessage(message)\ndiff --git a/Products/CMFPlone/controlpanel/browser/usergroups_usermembership.py b/Products/CMFPlone/controlpanel/browser/usergroups_usermembership.py\nindex 71a4e123b1..57ea21eeed 100644\n--- a/Products/CMFPlone/controlpanel/browser/usergroups_usermembership.py\n+++ b/Products/CMFPlone/controlpanel/browser/usergroups_usermembership.py\n@@ -8,44 +8,44 @@\n \n \n class UserMembershipControlPanel(UsersGroupsControlPanelView):\n-\n def update(self):\n- self.userid = getattr(self.request, \'userid\')\n- self.gtool = getToolByName(self, \'portal_groups\')\n- self.mtool = getToolByName(self, \'portal_membership\')\n+ self.userid = getattr(self.request, "userid")\n+ self.gtool = getToolByName(self, "portal_groups")\n+ self.mtool = getToolByName(self, "portal_membership")\n self.member = self.mtool.getMemberById(self.userid)\n \n form = self.request.form\n \n self.searchResults = []\n- self.searchString = \'\'\n+ self.searchString = ""\n self.newSearch = False\n \n- if form.get(\'form.submitted\', False):\n- delete = form.get(\'delete\', [])\n+ if form.get("form.submitted", False):\n+ delete = form.get("delete", [])\n if delete:\n for groupname in delete:\n self.gtool.removePrincipalFromGroup(\n- self.userid, groupname, self.request)\n- self.context.plone_utils.addPortalMessage(_(\'Changes made.\'))\n+ self.userid, groupname, self.request\n+ )\n+ self.context.plone_utils.addPortalMessage(_("Changes made."))\n \n- add = form.get(\'add\', [])\n+ add = form.get("add", [])\n if add:\n for groupname in add:\n group = self.gtool.getGroupById(groupname)\n- if \'Manager\' in group.getRoles() and not self.is_zope_manager:\n+ if "Manager" in group.getRoles() and not self.is_zope_manager:\n raise Forbidden\n \n- self.gtool.addPrincipalToGroup(\n- self.userid, groupname, self.request)\n- self.context.plone_utils.addPortalMessage(_(\'Changes made.\'))\n+ self.gtool.addPrincipalToGroup(self.userid, groupname, self.request)\n+ self.context.plone_utils.addPortalMessage(_("Changes made."))\n \n- search = form.get(\'form.button.Search\', None) is not None\n- findAll = form.get(\'form.button.FindAll\',\n- None) is not None and not self.many_groups\n- self.searchString = not findAll and form.get(\'searchstring\', \'\') or \'\'\n+ search = form.get("form.button.Search", None) is not None\n+ findAll = (\n+ form.get("form.button.FindAll", None) is not None and not self.many_groups\n+ )\n+ self.searchString = not findAll and form.get("searchstring", "") or ""\n \n- if findAll or not self.many_groups or self.searchString != \'\':\n+ if findAll or not self.many_groups or self.searchString != "":\n self.searchResults = self.getPotentialGroups(self.searchString)\n \n if search or findAll:\n@@ -58,12 +58,17 @@ def __call__(self):\n return self.index()\n \n def getGroups(self):\n- groupResults = [self.gtool.getGroupById(\n- m) for m in self.gtool.getGroupsForPrincipal(self.member)]\n- groupResults.sort(key=lambda x: x is not None and normalizeString(\n- x.getGroupTitleOrName()))\n+ groupResults = [\n+ self.gtool.getGroupById(m)\n+ for m in self.gtool.getGroupsForPrincipal(self.member)\n+ ]\n+ groupResults.sort(\n+ key=lambda x: x is not None and normalizeString(x.getGroupTitleOrName())\n+ )\n return [i for i in groupResults if i]\n \n def getPotentialGroups(self, searchString):\n ignoredGroups = [x.id for x in self.getGroups() if x is not None]\n- return self.membershipSearch(searchString, searchUsers=False, ignore=ignoredGroups)\n+ return self.membershipSearch(\n+ searchString, searchUsers=False, ignore=ignoredGroups\n+ )\ndiff --git a/Products/CMFPlone/controlpanel/browser/usergroups_usersoverview.py b/Products/CMFPlone/controlpanel/browser/usergroups_usersoverview.py\nindex 8c14b9ad82..e102111e40 100644\n--- a/Products/CMFPlone/controlpanel/browser/usergroups_usersoverview.py\n+++ b/Products/CMFPlone/controlpanel/browser/usergroups_usersoverview.py\n@@ -16,18 +16,16 @@\n import logging\n \n \n-logger = logging.getLogger(\'Products.CMFPlone\')\n+logger = logging.getLogger("Products.CMFPlone")\n \n \n class UsersOverviewControlPanel(UsersGroupsControlPanelView):\n-\n def __call__(self):\n-\n form = self.request.form\n- submitted = form.get(\'form.submitted\', False)\n- search = form.get(\'form.button.Search\', None) is not None\n- findAll = form.get(\'form.button.FindAll\', None) is not None\n- self.searchString = not findAll and form.get(\'searchstring\', \'\') or \'\'\n+ submitted = form.get("form.submitted", False)\n+ search = form.get("form.button.Search", None) is not None\n+ findAll = form.get("form.button.FindAll", None) is not None\n+ self.searchString = not findAll and form.get("searchstring", "") or ""\n self.searchResults = []\n self.newSearch = False\n \n@@ -35,43 +33,50 @@ def __call__(self):\n self.newSearch = True\n \n if submitted:\n- if form.get(\'form.button.Modify\', None) is not None:\n- self.manageUser(form.get(\'users\', None),\n- form.get(\'resetpassword\', []),\n- form.get(\'delete\', []))\n+ if form.get("form.button.Modify", None) is not None:\n+ self.manageUser(\n+ form.get("users", None),\n+ form.get("resetpassword", []),\n+ form.get("delete", []),\n+ )\n \n # Only search for all (\'\') if the many_users flag is not set.\n- if not(self.many_users) or bool(self.searchString):\n+ if not (self.many_users) or bool(self.searchString):\n self.searchResults = self.doSearch(self.searchString)\n \n return self.index()\n \n def doSearch(self, searchString):\n- acl = getToolByName(self, \'acl_users\')\n+ acl = getToolByName(self, "acl_users")\n rolemakers = acl.plugins.listPlugins(IRolesPlugin)\n \n- mtool = getToolByName(self, \'portal_membership\')\n+ mtool = getToolByName(self, "portal_membership")\n \n- searchView = getMultiAdapter((\n- aq_inner(self.context),\n- self.request\n- ), name=\'pas_search\')\n+ searchView = getMultiAdapter(\n+ (aq_inner(self.context), self.request), name="pas_search"\n+ )\n \n # First, search for all inherited roles assigned to each group.\n # We push this in the request so that IRoles plugins are told provide\n # the roles inherited from the groups to which the principal belongs.\n- self.request.set(\'__ignore_group_roles__\', False)\n- self.request.set(\'__ignore_direct_roles__\', True)\n+ self.request.set("__ignore_group_roles__", False)\n+ self.request.set("__ignore_direct_roles__", True)\n inheritance_enabled_users = searchView.merge(\n- chain(*[searchView.searchUsers(**{field: searchString}) for field in [\'login\', \'fullname\', \'email\']]), \'userid\')\n+ chain(\n+ *[\n+ searchView.searchUsers(**{field: searchString})\n+ for field in ["login", "fullname", "email"]\n+ ]\n+ ),\n+ "userid",\n+ )\n allInheritedRoles = {}\n for user_info in inheritance_enabled_users:\n- userId = user_info[\'id\']\n+ userId = user_info["id"]\n user = acl.getUserById(userId)\n # play safe, though this should never happen\n if user is None:\n- logger.warning(\n- \'Skipped user without principal object: %s\' % userId)\n+ logger.warning("Skipped user without principal object: %s" % userId)\n continue\n allAssignedRoles = []\n for rolemaker_id, rolemaker in rolemakers:\n@@ -80,11 +85,16 @@ def doSearch(self, searchString):\n \n # We push this in the request such IRoles plugins don\'t provide\n # the roles from the groups the principal belongs.\n- self.request.set(\'__ignore_group_roles__\', True)\n- self.request.set(\'__ignore_direct_roles__\', False)\n+ self.request.set("__ignore_group_roles__", True)\n+ self.request.set("__ignore_direct_roles__", False)\n explicit_users = searchView.merge(\n- chain(*[searchView.searchUsers(**{field: searchString})\n- for field in [\'login\', \'fullname\', \'email\']]), \'userid\'\n+ chain(\n+ *[\n+ searchView.searchUsers(**{field: searchString})\n+ for field in ["login", "fullname", "email"]\n+ ]\n+ ),\n+ "userid",\n )\n \n # Tack on some extra data, including whether each role is explicitly\n@@ -92,48 +102,52 @@ def doSearch(self, searchString):\n # all (None).\n results = []\n for user_info in explicit_users:\n- userId = user_info[\'id\']\n+ userId = user_info["id"]\n user = mtool.getMemberById(userId)\n # play safe, though this should never happen\n if user is None:\n- logger.warning(\n- \'Skipped user without principal object: %s\' % userId)\n+ logger.warning("Skipped user without principal object: %s" % userId)\n continue\n explicitlyAssignedRoles = []\n for rolemaker_id, rolemaker in rolemakers:\n- explicitlyAssignedRoles.extend(\n- rolemaker.getRolesForPrincipal(user))\n+ explicitlyAssignedRoles.extend(rolemaker.getRolesForPrincipal(user))\n \n roleList = {}\n for role in self.portal_roles:\n canAssign = user.canAssignRole(role)\n- if role == \'Manager\' and not self.is_zope_manager:\n+ if role == "Manager" and not self.is_zope_manager:\n canAssign = False\n- roleList[role] = {\'canAssign\': canAssign,\n- \'explicit\': role in explicitlyAssignedRoles,\n- \'inherited\': role in allInheritedRoles.get(userId, ())}\n+ roleList[role] = {\n+ "canAssign": canAssign,\n+ "explicit": role in explicitlyAssignedRoles,\n+ "inherited": role in allInheritedRoles.get(userId, ()),\n+ }\n \n canDelete = user.canDelete()\n canPasswordSet = user.canPasswordSet()\n- if roleList[\'Manager\'][\'explicit\'] or roleList[\'Manager\'][\'inherited\']:\n+ if roleList["Manager"]["explicit"] or roleList["Manager"]["inherited"]:\n if not self.is_zope_manager:\n canDelete = False\n canPasswordSet = False\n \n- user_info[\'roles\'] = roleList\n- user_info[\'fullname\'] = user.getProperty(\'fullname\', \'\')\n- user_info[\'email\'] = user.getProperty(\'email\', \'\')\n- user_info[\'can_delete\'] = canDelete\n- user_info[\'can_set_email\'] = user.canWriteProperty(\'email\')\n- user_info[\'can_set_password\'] = canPasswordSet\n+ user_info["roles"] = roleList\n+ user_info["fullname"] = user.getProperty("fullname", "")\n+ user_info["email"] = user.getProperty("email", "")\n+ user_info["can_delete"] = canDelete\n+ user_info["can_set_email"] = user.canWriteProperty("email")\n+ user_info["can_set_password"] = canPasswordSet\n results.append(user_info)\n \n # Sort the users by fullname\n- results.sort(key=lambda x: x is not None and x[\n- \'fullname\'] is not None and normalizeString(x[\'fullname\']) or \'\')\n+ results.sort(\n+ key=lambda x: x is not None\n+ and x["fullname"] is not None\n+ and normalizeString(x["fullname"])\n+ or ""\n+ )\n \n # Reset the request variable, just in case.\n- self.request.set(\'__ignore_group_roles__\', False)\n+ self.request.set("__ignore_group_roles__", False)\n return results\n \n def manageUser(self, users=[], resetpassword=[], delete=[]):\n@@ -141,11 +155,11 @@ def manageUser(self, users=[], resetpassword=[], delete=[]):\n \n if users:\n context = aq_inner(self.context)\n- acl_users = getToolByName(context, \'acl_users\')\n- mtool = getToolByName(context, \'portal_membership\')\n- regtool = getToolByName(context, \'portal_registration\')\n+ acl_users = getToolByName(context, "acl_users")\n+ mtool = getToolByName(context, "portal_membership")\n+ regtool = getToolByName(context, "portal_registration")\n \n- utils = getToolByName(context, \'plone_utils\')\n+ utils = getToolByName(context, "plone_utils")\n \n users_with_reset_passwords = []\n \n@@ -157,35 +171,41 @@ def manageUser(self, users=[], resetpassword=[], delete=[]):\n member = mtool.getMemberById(user.id)\n current_roles = member.getRoles()\n # If email address was changed, set the new one\n- if hasattr(user, \'email\'):\n+ if hasattr(user, "email"):\n # If the email field was disabled (ie: non-writeable), the\n # property might not exist.\n- if user.email != member.getProperty(\'email\'):\n+ if user.email != member.getProperty("email"):\n utils.setMemberProperties(\n- member, REQUEST=context.REQUEST, email=user.email)\n- utils.addPortalMessage(_(\'Changes applied.\'))\n+ member, REQUEST=context.REQUEST, email=user.email\n+ )\n+ utils.addPortalMessage(_("Changes applied."))\n \n # If reset password has been checked email user a new password\n pw = None\n- if hasattr(user, \'resetpassword\'):\n- if \'Manager\' in current_roles and not self.is_zope_manager:\n+ if hasattr(user, "resetpassword"):\n+ if "Manager" in current_roles and not self.is_zope_manager:\n raise Forbidden\n- if not context.unrestrictedTraverse(\'@@overview-controlpanel\').mailhost_warning():\n+ if not context.unrestrictedTraverse(\n+ "@@overview-controlpanel"\n+ ).mailhost_warning():\n pw = regtool.generatePassword()\n else:\n utils.addPortalMessage(\n- _(\'No mailhost defined. Unable to reset passwords.\'), type=\'error\')\n+ _("No mailhost defined. Unable to reset passwords."),\n+ type="error",\n+ )\n \n- roles = user.get(\'roles\', [])\n+ roles = user.get("roles", [])\n if not self.is_zope_manager:\n # don\'t allow adding or removing the Manager role\n- if (\'Manager\' in roles) != (\'Manager\' in current_roles):\n+ if ("Manager" in roles) != ("Manager" in current_roles):\n raise Forbidden\n \n acl_users.userFolderEditUser(\n- user.id, pw, roles, member.getDomains(), REQUEST=context.REQUEST)\n+ user.id, pw, roles, member.getDomains(), REQUEST=context.REQUEST\n+ )\n if pw:\n- context.REQUEST.form[\'new_password\'] = pw\n+ context.REQUEST.form["new_password"] = pw\n regtool.mailPassword(user.id, context.REQUEST)\n users_with_reset_passwords.append(user.id)\n \n@@ -196,17 +216,17 @@ def manageUser(self, users=[], resetpassword=[], delete=[]):\n "reset_passwords_msg",\n default="The following users have been sent an e-mail with link to reset their password: ${user_ids}",\n mapping={\n- "user_ids": \', \'.join(users_with_reset_passwords),\n+ "user_ids": ", ".join(users_with_reset_passwords),\n },\n )\n utils.addPortalMessage(reset_passwords_message)\n- utils.addPortalMessage(_(\'Changes applied.\'))\n+ utils.addPortalMessage(_("Changes applied."))\n \n def deleteMembers(self, member_ids):\n # this method exists to bypass the \'Manage Users\' permission check\n # in the CMF member tool\'s version\n context = aq_inner(self.context)\n- mtool = getToolByName(self.context, \'portal_membership\')\n+ mtool = getToolByName(self.context, "portal_membership")\n \n # Delete members in acl_users.\n acl_users = context.acl_users\n@@ -220,24 +240,22 @@ def deleteMembers(self, member_ids):\n else:\n if not member.canDelete():\n raise Forbidden\n- if \'Manager\' in member.getRoles() and not self.is_zope_manager:\n+ if "Manager" in member.getRoles() and not self.is_zope_manager:\n raise Forbidden\n try:\n acl_users.userFolderDelUsers(member_ids)\n except (AttributeError, NotImplementedError):\n- raise NotImplementedError(\'The underlying User Folder \'\n- \'doesn\\\'t support deleting members.\')\n+ raise NotImplementedError(\n+ "The underlying User Folder " "doesn\'t support deleting members."\n+ )\n \n # Delete member data in portal_memberdata.\n- mdtool = getToolByName(context, \'portal_memberdata\', None)\n+ mdtool = getToolByName(context, "portal_memberdata", None)\n if mdtool is not None:\n for member_id in member_ids:\n mdtool.deleteMemberData(member_id)\n \n # Delete members\' local roles.\n mtool.deleteLocalRoles(\n- getUtility(ISiteRoot),\n- member_ids,\n- reindex=1,\n- recursive=1\n+ getUtility(ISiteRoot), member_ids, reindex=1, recursive=1\n )\ndiff --git a/Products/CMFPlone/controlpanel/events.py b/Products/CMFPlone/controlpanel/events.py\nindex 4d4d34df0f..b7fbc26cd8 100644\n--- a/Products/CMFPlone/controlpanel/events.py\n+++ b/Products/CMFPlone/controlpanel/events.py\n@@ -16,7 +16,6 @@\n \n @implementer(IConfigurationChangedEvent)\n class ConfigurationChangedEvent:\n-\n def __init__(self, context, data):\n self.context = context\n self.data = data\n@@ -38,25 +37,23 @@ def handle_enable_self_reg(obj, event):\n added to ``Anonymous`` role to allow self registration for anonymous\n users. If the setting is disabled, this permission is removed.\n """\n- if event.record.fieldName != \'enable_self_reg\':\n+ if event.record.fieldName != "enable_self_reg":\n return\n \n portal = getSite()\n value = event.newValue\n- app_perms = portal.rolesOfPermission(\n- permission=\'Add portal member\')\n+ app_perms = portal.rolesOfPermission(permission="Add portal member")\n reg_roles = []\n \n for app_perm in app_perms:\n- if app_perm[\'selected\'] == \'SELECTED\':\n- reg_roles.append(app_perm[\'name\'])\n- if value is True and \'Anonymous\' not in reg_roles:\n- reg_roles.append(\'Anonymous\')\n- if value is False and \'Anonymous\' in reg_roles:\n- reg_roles.remove(\'Anonymous\')\n+ if app_perm["selected"] == "SELECTED":\n+ reg_roles.append(app_perm["name"])\n+ if value is True and "Anonymous" not in reg_roles:\n+ reg_roles.append("Anonymous")\n+ if value is False and "Anonymous" in reg_roles:\n+ reg_roles.remove("Anonymous")\n \n- portal.manage_permission(\'Add portal member\', roles=reg_roles,\n- acquire=0)\n+ portal.manage_permission("Add portal member", roles=reg_roles, acquire=0)\n \n \n @adapter(ISecuritySchema, IRecordModifiedEvent)\n@@ -67,42 +64,42 @@ def handle_enable_user_folders(obj, event):\n If the setting is enabled, a new user action is added with a link to\n the personal folder. If the setting is disabled, the action is hidden.\n """\n- if event.record.fieldName != \'enable_user_folders\':\n+ if event.record.fieldName != "enable_user_folders":\n return\n \n portal = getSite()\n value = event.newValue\n \n- membership = getToolByName(portal, \'portal_membership\')\n+ membership = getToolByName(portal, "portal_membership")\n membership.memberareaCreationFlag = value\n \n # support the \'my folder\' user action #8417\n- portal_actions = getToolByName(portal, \'portal_actions\', None)\n+ portal_actions = getToolByName(portal, "portal_actions", None)\n if portal_actions is not None:\n- object_category = getattr(portal_actions, \'user\', None)\n- if value and not safe_hasattr(object_category, \'mystuff\'):\n+ object_category = getattr(portal_actions, "user", None)\n+ if value and not safe_hasattr(object_category, "mystuff"):\n # add action\n _add_mystuff_action(object_category)\n- elif safe_hasattr(object_category, \'mystuff\'):\n- a = getattr(object_category, \'mystuff\')\n- a.visible = bool(value) # show/hide action\n+ elif safe_hasattr(object_category, "mystuff"):\n+ a = getattr(object_category, "mystuff")\n+ a.visible = bool(value) # show/hide action\n \n \n def _add_mystuff_action(object_category):\n new_action = Action(\n- \'mystuff\',\n- title=_(\'My Folder\'),\n- description=\'\',\n- url_expr=\'string:${portal/portal_membership/getHomeUrl}\',\n- available_expr=\'python:(member is not None) and \\\n- (portal.portal_membership.getHomeFolder() is not None) \',\n- permissions=(\'View\',),\n+ "mystuff",\n+ title=_("My Folder"),\n+ description="",\n+ url_expr="string:${portal/portal_membership/getHomeUrl}",\n+ available_expr="python:(member is not None) and \\\n+ (portal.portal_membership.getHomeFolder() is not None) ",\n+ permissions=("View",),\n visible=True,\n- i18n_domain=\'plone\'\n+ i18n_domain="plone",\n )\n- object_category._setObject(\'mystuff\', new_action)\n+ object_category._setObject("mystuff", new_action)\n # move action to top, at least before the logout action\n- object_category.moveObjectsToTop(\'mystuff\')\n+ object_category.moveObjectsToTop("mystuff")\n \n \n @adapter(ISecuritySchema, IRecordModifiedEvent)\n@@ -114,7 +111,7 @@ def handle_use_email_as_login(obj, event):\n to email. If the setting is disabled, then the login names are migrated\n back to user ids.\n """\n- if event.record.fieldName != \'use_email_as_login\':\n+ if event.record.fieldName != "use_email_as_login":\n return\n \n value = event.newValue\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_actions.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_actions.py\nindex 4261a8e4e8..09f688a586 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_actions.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_actions.py\n@@ -11,29 +11,28 @@ class PortalActionsIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self): # NOQA\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- self.portal_actions = getToolByName(self.portal, \'portal_actions\')\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ self.portal_actions = getToolByName(self.portal, "portal_actions")\n \n def test_actions_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="actions-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="actions-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_actions_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'ActionSettings\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "ActionSettings"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_edit_action_controlpanel_view(self):\n action = self.portal_actions.site_actions.sitemap\n- view = getMultiAdapter((action, self.portal.REQUEST),\n- name="action-form")\n+ view = getMultiAdapter((action, self.portal.REQUEST), name="action-form")\n self.assertTrue(view())\n \n def test_new_action_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="new-action")\n+ view = getMultiAdapter((self.portal, self.portal.REQUEST), name="new-action")\n self.assertTrue(view())\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_editing_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_editing_adapter.py\nindex 4cb4c82690..a44d63465a 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_editing_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_editing_adapter.py\n@@ -10,103 +10,70 @@\n \n \n class EditingControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(IEditingSchema, prefix=\'plone\')\n+ self.settings = registry.forInterface(IEditingSchema, prefix="plone")\n \n def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, IEditingSchema))\n \n def test_get_enable_link_integrity_checks_setting(self):\n self.assertEqual(\n- getAdapter(self.portal, IEditingSchema).enable_link_integrity_checks, # noqa\n- True\n+ getAdapter(\n+ self.portal, IEditingSchema\n+ ).enable_link_integrity_checks, # noqa\n+ True,\n )\n self.settings.enable_link_integrity_checks = False\n self.assertEqual(\n- getAdapter(self.portal, IEditingSchema).enable_link_integrity_checks, # noqa\n- False\n+ getAdapter(\n+ self.portal, IEditingSchema\n+ ).enable_link_integrity_checks, # noqa\n+ False,\n )\n \n def test_set_enable_link_integrity_checks_setting(self):\n- self.assertEqual(\n- self.settings.enable_link_integrity_checks,\n- True\n- )\n- getAdapter(self.portal, IEditingSchema).enable_link_integrity_checks = False # noqa\n- self.assertEqual(\n- self.settings.enable_link_integrity_checks,\n- False\n- )\n+ self.assertEqual(self.settings.enable_link_integrity_checks, True)\n+ getAdapter(\n+ self.portal, IEditingSchema\n+ ).enable_link_integrity_checks = False # noqa\n+ self.assertEqual(self.settings.enable_link_integrity_checks, False)\n \n def test_get_ext_editor_setting(self):\n- self.assertEqual(\n- getAdapter(self.portal, IEditingSchema).ext_editor,\n- False\n- )\n+ self.assertEqual(getAdapter(self.portal, IEditingSchema).ext_editor, False)\n self.settings.ext_editor = True\n- self.assertEqual(\n- getAdapter(self.portal, IEditingSchema).ext_editor,\n- True\n- )\n+ self.assertEqual(getAdapter(self.portal, IEditingSchema).ext_editor, True)\n \n def test_set_ext_editor_setting(self):\n- self.assertEqual(\n- self.settings.ext_editor,\n- False\n- )\n+ self.assertEqual(self.settings.ext_editor, False)\n getAdapter(self.portal, IEditingSchema).ext_editor = True\n- self.assertEqual(\n- self.settings.ext_editor,\n- True\n- )\n+ self.assertEqual(self.settings.ext_editor, True)\n \n def test_get_default_editor_setting(self):\n self.assertEqual(\n- getAdapter(self.portal, IEditingSchema).default_editor,\n- \'TinyMCE\'\n- )\n- self.settings.default_editor = \'None\'\n- self.assertEqual(\n- getAdapter(self.portal, IEditingSchema).default_editor,\n- \'None\'\n+ getAdapter(self.portal, IEditingSchema).default_editor, "TinyMCE"\n )\n+ self.settings.default_editor = "None"\n+ self.assertEqual(getAdapter(self.portal, IEditingSchema).default_editor, "None")\n \n def test_set_default_editor_setting(self):\n- self.assertEqual(\n- self.settings.default_editor,\n- \'TinyMCE\'\n- )\n- getAdapter(self.portal, IEditingSchema).default_editor = \'None\'\n- self.assertEqual(\n- self.settings.default_editor,\n- \'None\'\n- )\n+ self.assertEqual(self.settings.default_editor, "TinyMCE")\n+ getAdapter(self.portal, IEditingSchema).default_editor = "None"\n+ self.assertEqual(self.settings.default_editor, "None")\n \n def test_get_lock_on_ttw_edit_setting(self):\n- self.assertEqual(\n- getAdapter(self.portal, IEditingSchema).lock_on_ttw_edit,\n- True\n- )\n+ self.assertEqual(getAdapter(self.portal, IEditingSchema).lock_on_ttw_edit, True)\n self.settings.lock_on_ttw_edit = False\n self.assertEqual(\n- getAdapter(self.portal, IEditingSchema).lock_on_ttw_edit,\n- False\n+ getAdapter(self.portal, IEditingSchema).lock_on_ttw_edit, False\n )\n \n def test_set_lock_on_ttw_edit_setting(self):\n- self.assertEqual(\n- self.settings.lock_on_ttw_edit,\n- True\n- )\n+ self.assertEqual(self.settings.lock_on_ttw_edit, True)\n getAdapter(self.portal, IEditingSchema).lock_on_ttw_edit = False\n- self.assertEqual(\n- self.settings.lock_on_ttw_edit,\n- False\n- )\n+ self.assertEqual(self.settings.lock_on_ttw_edit, False)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_filter_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_filter_adapter.py\nindex 1558e1d814..f6f3794f91 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_filter_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_filter_adapter.py\n@@ -10,13 +10,12 @@\n \n \n class FilterControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n self.settings = registry.forInterface(IFilterSchema, prefix="plone")\n \n@@ -24,45 +23,31 @@ def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, IFilterSchema))\n \n def test_get_nasty_tags(self):\n- self.settings.nasty_tags = [\'foo\', \'bar\']\n+ self.settings.nasty_tags = ["foo", "bar"]\n self.assertEqual(\n- getAdapter(self.portal, IFilterSchema).nasty_tags,\n- [\'foo\', \'bar\']\n+ getAdapter(self.portal, IFilterSchema).nasty_tags, ["foo", "bar"]\n )\n \n def test_set_nasty_tags(self):\n- getAdapter(self.portal, IFilterSchema).nasty_tags = [\'foo\', \'bar\']\n- self.assertEqual(\n- self.settings.nasty_tags,\n- [\'foo\', \'bar\']\n- )\n+ getAdapter(self.portal, IFilterSchema).nasty_tags = ["foo", "bar"]\n+ self.assertEqual(self.settings.nasty_tags, ["foo", "bar"])\n \n def test_get_valid_tags(self):\n- self.settings.valid_tags = [\'foo\', \'bar\']\n+ self.settings.valid_tags = ["foo", "bar"]\n self.assertEqual(\n- getAdapter(self.portal, IFilterSchema).valid_tags,\n- [\'foo\', \'bar\']\n+ getAdapter(self.portal, IFilterSchema).valid_tags, ["foo", "bar"]\n )\n \n def test_set_valid_tags(self):\n- getAdapter(self.portal, IFilterSchema).valid_tags = [\'foo\', \'bar\']\n- self.assertEqual(\n- self.settings.valid_tags,\n- [\'foo\', \'bar\']\n- )\n+ getAdapter(self.portal, IFilterSchema).valid_tags = ["foo", "bar"]\n+ self.assertEqual(self.settings.valid_tags, ["foo", "bar"])\n \n def test_get_custom_attributes(self):\n- self.settings.custom_attributes = [\'foo\', \'bar\']\n+ self.settings.custom_attributes = ["foo", "bar"]\n self.assertEqual(\n- getAdapter(self.portal, IFilterSchema).custom_attributes,\n- [\'foo\', \'bar\']\n+ getAdapter(self.portal, IFilterSchema).custom_attributes, ["foo", "bar"]\n )\n \n def test_set_custom_attributes(self):\n- getAdapter(self.portal, IFilterSchema).custom_attributes = [\n- \'foo\', \'bar\'\n- ]\n- self.assertEqual(\n- self.settings.custom_attributes,\n- [\'foo\', \'bar\']\n- )\n+ getAdapter(self.portal, IFilterSchema).custom_attributes = ["foo", "bar"]\n+ self.assertEqual(self.settings.custom_attributes, ["foo", "bar"])\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_language_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_language_adapter.py\nindex 724b1f20f4..410d94f812 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_language_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_language_adapter.py\n@@ -10,302 +10,178 @@\n \n \n class LanguageControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ILanguageSchema, prefix="plone")\n+ self.settings = registry.forInterface(ILanguageSchema, prefix="plone")\n \n def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, ILanguageSchema))\n \n def test_get_default_language(self):\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).default_language,\n- \'en\'\n+ getAdapter(self.portal, ILanguageSchema).default_language, "en"\n )\n- self.settings.default_language = \'de\'\n+ self.settings.default_language = "de"\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).default_language,\n- \'de\'\n+ getAdapter(self.portal, ILanguageSchema).default_language, "de"\n )\n \n def test_set_default_language(self):\n- self.assertEqual(\n- self.settings.default_language,\n- \'en\'\n- )\n- getAdapter(self.portal, ILanguageSchema).default_language = \'de\'\n- self.assertEqual(\n- self.settings.default_language,\n- \'de\'\n- )\n+ self.assertEqual(self.settings.default_language, "en")\n+ getAdapter(self.portal, ILanguageSchema).default_language = "de"\n+ self.assertEqual(self.settings.default_language, "de")\n \n def test_get_available_languages(self):\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).available_languages,\n- [\'en\']\n+ getAdapter(self.portal, ILanguageSchema).available_languages, ["en"]\n )\n- self.settings.available_languages = [\'en\', \'de\']\n+ self.settings.available_languages = ["en", "de"]\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).available_languages,\n- [\'en\', \'de\']\n+ getAdapter(self.portal, ILanguageSchema).available_languages, ["en", "de"]\n )\n \n def test_set_available_languages(self):\n- self.assertEqual(\n- self.settings.available_languages,\n- [\'en\']\n- )\n- getAdapter(self.portal, ILanguageSchema).available_languages = [\n- \'de\', \'en\']\n- self.assertEqual(\n- self.settings.available_languages,\n- [\'de\', \'en\']\n- )\n+ self.assertEqual(self.settings.available_languages, ["en"])\n+ getAdapter(self.portal, ILanguageSchema).available_languages = ["de", "en"]\n+ self.assertEqual(self.settings.available_languages, ["de", "en"])\n \n def test_get_use_combined_language_codes(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).use_combined_language_codes,\n- True\n+ getAdapter(self.portal, ILanguageSchema).use_combined_language_codes, True\n )\n self.settings.use_combined_language_codes = False\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).use_combined_language_codes,\n- False\n+ getAdapter(self.portal, ILanguageSchema).use_combined_language_codes, False\n )\n \n def test_set_use_combined_language_codes(self):\n- self.assertEqual(\n- self.settings.use_combined_language_codes,\n- True\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).use_combined_language_codes = False\n- self.assertEqual(\n- self.settings.use_combined_language_codes,\n- False\n- )\n+ self.assertEqual(self.settings.use_combined_language_codes, True)\n+ getAdapter(self.portal, ILanguageSchema).use_combined_language_codes = False\n+ self.assertEqual(self.settings.use_combined_language_codes, False)\n \n def test_get_display_flags(self):\n- self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).display_flags,\n- False\n- )\n+ self.assertEqual(getAdapter(self.portal, ILanguageSchema).display_flags, False)\n self.settings.display_flags = True\n- self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).display_flags,\n- True\n- )\n+ self.assertEqual(getAdapter(self.portal, ILanguageSchema).display_flags, True)\n \n def test_set_display_flags(self):\n- self.assertEqual(\n- self.settings.display_flags,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).display_flags = True\n- self.assertEqual(\n- self.settings.display_flags,\n- True\n- )\n+ self.assertEqual(self.settings.display_flags, False)\n+ getAdapter(self.portal, ILanguageSchema).display_flags = True\n+ self.assertEqual(self.settings.display_flags, True)\n \n def test_get_use_content_negotiation(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).use_content_negotiation,\n- False\n+ getAdapter(self.portal, ILanguageSchema).use_content_negotiation, False\n )\n self.settings.use_content_negotiation = True\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).use_content_negotiation,\n- True\n+ getAdapter(self.portal, ILanguageSchema).use_content_negotiation, True\n )\n \n def test_set_use_content_negotiation(self):\n- self.assertEqual(\n- self.settings.use_content_negotiation,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).use_content_negotiation = True\n- self.assertEqual(\n- self.settings.use_content_negotiation,\n- True\n- )\n+ self.assertEqual(self.settings.use_content_negotiation, False)\n+ getAdapter(self.portal, ILanguageSchema).use_content_negotiation = True\n+ self.assertEqual(self.settings.use_content_negotiation, True)\n \n def test_get_use_path_negotiation(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).use_path_negotiation,\n- False\n+ getAdapter(self.portal, ILanguageSchema).use_path_negotiation, False\n )\n self.settings.use_path_negotiation = True\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).use_path_negotiation,\n- True\n+ getAdapter(self.portal, ILanguageSchema).use_path_negotiation, True\n )\n \n def test_set_use_path_negotiation(self):\n- self.assertEqual(\n- self.settings.use_path_negotiation,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).use_path_negotiation = True\n- self.assertEqual(\n- self.settings.use_path_negotiation,\n- True\n- )\n+ self.assertEqual(self.settings.use_path_negotiation, False)\n+ getAdapter(self.portal, ILanguageSchema).use_path_negotiation = True\n+ self.assertEqual(self.settings.use_path_negotiation, True)\n \n def test_get_use_cookie_negotiation(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).use_cookie_negotiation,\n- False\n+ getAdapter(self.portal, ILanguageSchema).use_cookie_negotiation, False\n )\n self.settings.use_cookie_negotiation = True\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).use_cookie_negotiation,\n- True\n+ getAdapter(self.portal, ILanguageSchema).use_cookie_negotiation, True\n )\n \n def test_set_use_cookie_negotiation(self):\n- self.assertEqual(\n- self.settings.use_cookie_negotiation,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).use_cookie_negotiation = True\n- self.assertEqual(\n- self.settings.use_cookie_negotiation,\n- True\n- )\n+ self.assertEqual(self.settings.use_cookie_negotiation, False)\n+ getAdapter(self.portal, ILanguageSchema).use_cookie_negotiation = True\n+ self.assertEqual(self.settings.use_cookie_negotiation, True)\n \n def test_get_authenticated_users_only(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).authenticated_users_only,\n- False\n+ getAdapter(self.portal, ILanguageSchema).authenticated_users_only, False\n )\n self.settings.authenticated_users_only = True\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).authenticated_users_only,\n- True\n+ getAdapter(self.portal, ILanguageSchema).authenticated_users_only, True\n )\n \n def test_set_authenticated_users_only(self):\n- self.assertEqual(\n- self.settings.authenticated_users_only,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).authenticated_users_only = True\n- self.assertEqual(\n- self.settings.authenticated_users_only,\n- True\n- )\n+ self.assertEqual(self.settings.authenticated_users_only, False)\n+ getAdapter(self.portal, ILanguageSchema).authenticated_users_only = True\n+ self.assertEqual(self.settings.authenticated_users_only, True)\n \n def test_get_set_cookie_always(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).set_cookie_always,\n- False\n+ getAdapter(self.portal, ILanguageSchema).set_cookie_always, False\n )\n self.settings.set_cookie_always = True\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).set_cookie_always,\n- True\n+ getAdapter(self.portal, ILanguageSchema).set_cookie_always, True\n )\n \n def test_set_set_cookie_always(self):\n- self.assertEqual(\n- self.settings.set_cookie_always,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).set_cookie_always = True\n- self.assertEqual(\n- self.settings.set_cookie_always,\n- True\n- )\n+ self.assertEqual(self.settings.set_cookie_always, False)\n+ getAdapter(self.portal, ILanguageSchema).set_cookie_always = True\n+ self.assertEqual(self.settings.set_cookie_always, True)\n \n def test_get_use_subdomain_negotiation(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).use_subdomain_negotiation,\n- False\n+ getAdapter(self.portal, ILanguageSchema).use_subdomain_negotiation, False\n )\n self.settings.use_subdomain_negotiation = True\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).use_subdomain_negotiation,\n- True\n+ getAdapter(self.portal, ILanguageSchema).use_subdomain_negotiation, True\n )\n \n def test_set_use_subdomain_negotiation(self):\n- self.assertEqual(\n- self.settings.use_subdomain_negotiation,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).use_subdomain_negotiation = True\n- self.assertEqual(\n- self.settings.use_subdomain_negotiation,\n- True\n- )\n+ self.assertEqual(self.settings.use_subdomain_negotiation, False)\n+ getAdapter(self.portal, ILanguageSchema).use_subdomain_negotiation = True\n+ self.assertEqual(self.settings.use_subdomain_negotiation, True)\n \n def test_get_use_cctld_negotiation(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).use_cctld_negotiation,\n- False\n+ getAdapter(self.portal, ILanguageSchema).use_cctld_negotiation, False\n )\n self.settings.use_cctld_negotiation = True\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).use_cctld_negotiation,\n- True\n+ getAdapter(self.portal, ILanguageSchema).use_cctld_negotiation, True\n )\n \n def test_set_use_cctld_negotiation(self):\n- self.assertEqual(\n- self.settings.use_cctld_negotiation,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).use_cctld_negotiation = True\n- self.assertEqual(\n- self.settings.use_cctld_negotiation,\n- True\n- )\n+ self.assertEqual(self.settings.use_cctld_negotiation, False)\n+ getAdapter(self.portal, ILanguageSchema).use_cctld_negotiation = True\n+ self.assertEqual(self.settings.use_cctld_negotiation, True)\n \n def test_get_use_request_negotiation(self):\n self.assertEqual(\n- getAdapter(\n- self.portal, ILanguageSchema).use_request_negotiation,\n- False\n+ getAdapter(self.portal, ILanguageSchema).use_request_negotiation, False\n )\n self.settings.use_request_negotiation = True\n self.assertEqual(\n- getAdapter(self.portal, ILanguageSchema).use_request_negotiation,\n- True\n+ getAdapter(self.portal, ILanguageSchema).use_request_negotiation, True\n )\n \n def test_set_use_request_negotiation(self):\n- self.assertEqual(\n- self.settings.use_request_negotiation,\n- False\n- )\n- getAdapter(\n- self.portal, ILanguageSchema).use_request_negotiation = True\n- self.assertEqual(\n- self.settings.use_request_negotiation,\n- True\n- )\n+ self.assertEqual(self.settings.use_request_negotiation, False)\n+ getAdapter(self.portal, ILanguageSchema).use_request_negotiation = True\n+ self.assertEqual(self.settings.use_request_negotiation, True)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_mail_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_mail_adapter.py\nindex ecf2feb855..9eef6ce6f8 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_mail_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_mail_adapter.py\n@@ -10,149 +10,78 @@\n \n \n class MailControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n- self.mail_settings = registry.forInterface(\n- IMailSchema, prefix="plone")\n+ self.mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n \n def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, IMailSchema))\n \n def test_get_smtp_host(self):\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).smtp_host,\n- \'localhost\'\n- )\n- self.mail_settings.smtp_host = \'example.com\'\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).smtp_host,\n- \'example.com\'\n- )\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).smtp_host, "localhost")\n+ self.mail_settings.smtp_host = "example.com"\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).smtp_host, "example.com")\n \n def test_set_smtp_host(self):\n- self.assertEqual(\n- self.mail_settings.smtp_host,\n- \'localhost\'\n- )\n- getAdapter(self.portal, IMailSchema).smtp_host = \'example.com\'\n- self.assertEqual(\n- self.mail_settings.smtp_host,\n- \'example.com\'\n- )\n+ self.assertEqual(self.mail_settings.smtp_host, "localhost")\n+ getAdapter(self.portal, IMailSchema).smtp_host = "example.com"\n+ self.assertEqual(self.mail_settings.smtp_host, "example.com")\n \n def test_get_smtp_port(self):\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).smtp_port,\n- 25\n- )\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).smtp_port, 25)\n self.mail_settings.smtp_port = 88\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).smtp_port,\n- 88\n- )\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).smtp_port, 88)\n \n def test_set_smtp_port(self):\n- self.assertEqual(\n- self.mail_settings.smtp_port,\n- 25\n- )\n+ self.assertEqual(self.mail_settings.smtp_port, 25)\n getAdapter(self.portal, IMailSchema).smtp_port = 88\n- self.assertEqual(\n- self.mail_settings.smtp_port,\n- 88\n- )\n+ self.assertEqual(self.mail_settings.smtp_port, 88)\n \n def test_get_smtp_userid(self):\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).smtp_userid, None)\n+ self.mail_settings.smtp_userid = "john@example.com"\n self.assertEqual(\n- getAdapter(self.portal, IMailSchema).smtp_userid,\n- None\n- )\n- self.mail_settings.smtp_userid = \'john@example.com\'\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).smtp_userid,\n- \'john@example.com\'\n+ getAdapter(self.portal, IMailSchema).smtp_userid, "john@example.com"\n )\n \n def test_set_smtp_userid(self):\n- self.assertEqual(\n- self.mail_settings.smtp_userid,\n- None\n- )\n- getAdapter(self.portal, IMailSchema).smtp_userid = \'john@example.com\'\n- self.assertEqual(\n- self.mail_settings.smtp_userid,\n- \'john@example.com\'\n- )\n+ self.assertEqual(self.mail_settings.smtp_userid, None)\n+ getAdapter(self.portal, IMailSchema).smtp_userid = "john@example.com"\n+ self.assertEqual(self.mail_settings.smtp_userid, "john@example.com")\n \n def test_get_smtp_pass(self):\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).smtp_pass,\n- None\n- )\n- self.mail_settings.smtp_pass = \'secret\'\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).smtp_pass,\n- \'secret\'\n- )\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).smtp_pass, None)\n+ self.mail_settings.smtp_pass = "secret"\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).smtp_pass, "secret")\n \n def test_set_smtp_pass(self):\n- self.assertEqual(\n- self.mail_settings.smtp_pass,\n- None\n- )\n- getAdapter(self.portal, IMailSchema).smtp_pass = \'secret\'\n- self.assertEqual(\n- self.mail_settings.smtp_pass,\n- \'secret\'\n- )\n+ self.assertEqual(self.mail_settings.smtp_pass, None)\n+ getAdapter(self.portal, IMailSchema).smtp_pass = "secret"\n+ self.assertEqual(self.mail_settings.smtp_pass, "secret")\n \n def test_get_email_from_name(self):\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).email_from_name,\n- None\n- )\n- self.mail_settings.email_from_name = \'John\'\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).email_from_name,\n- \'John\'\n- )\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).email_from_name, None)\n+ self.mail_settings.email_from_name = "John"\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).email_from_name, "John")\n \n def test_set_email_from_name(self):\n- self.assertEqual(\n- self.mail_settings.email_from_name,\n- None\n- )\n- getAdapter(self.portal, IMailSchema).email_from_name = \'John\'\n- self.assertEqual(\n- self.mail_settings.email_from_name,\n- \'John\'\n- )\n+ self.assertEqual(self.mail_settings.email_from_name, None)\n+ getAdapter(self.portal, IMailSchema).email_from_name = "John"\n+ self.assertEqual(self.mail_settings.email_from_name, "John")\n \n def test_get_email_from_address(self):\n+ self.assertEqual(getAdapter(self.portal, IMailSchema).email_from_address, None)\n+ self.mail_settings.email_from_address = "john@example.com"\n self.assertEqual(\n- getAdapter(self.portal, IMailSchema).email_from_address,\n- None\n- )\n- self.mail_settings.email_from_address = \'john@example.com\'\n- self.assertEqual(\n- getAdapter(self.portal, IMailSchema).email_from_address,\n- \'john@example.com\'\n+ getAdapter(self.portal, IMailSchema).email_from_address, "john@example.com"\n )\n \n def test_set_email_from_address(self):\n- self.assertEqual(\n- self.mail_settings.email_from_address,\n- None\n- )\n- getAdapter(self.portal, IMailSchema).email_from_address = \\\n- \'john@example.com\'\n- self.assertEqual(\n- self.mail_settings.email_from_address,\n- \'john@example.com\'\n- )\n+ self.assertEqual(self.mail_settings.email_from_address, None)\n+ getAdapter(self.portal, IMailSchema).email_from_address = "john@example.com"\n+ self.assertEqual(self.mail_settings.email_from_address, "john@example.com")\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_maintenance_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_maintenance_adapter.py\nindex ab48904965..5df474be72 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_maintenance_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_maintenance_adapter.py\n@@ -10,40 +10,26 @@\n \n \n class MaintenanceControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n self.maintenance_settings = registry.forInterface(\n- IMaintenanceSchema, prefix="plone")\n+ IMaintenanceSchema, prefix="plone"\n+ )\n \n def test_adapter_lookup(self):\n- self.assertTrue(\n- getAdapter(self.portal, IMaintenanceSchema)\n- )\n+ self.assertTrue(getAdapter(self.portal, IMaintenanceSchema))\n \n def test_get_days(self):\n- self.assertEqual(\n- getAdapter(self.portal, IMaintenanceSchema).days,\n- 7\n- )\n+ self.assertEqual(getAdapter(self.portal, IMaintenanceSchema).days, 7)\n self.maintenance_settings.days = 4\n- self.assertEqual(\n- getAdapter(self.portal, IMaintenanceSchema).days,\n- 4\n- )\n+ self.assertEqual(getAdapter(self.portal, IMaintenanceSchema).days, 4)\n \n def test_set_days(self):\n- self.assertEqual(\n- self.maintenance_settings.days,\n- 7\n- )\n+ self.assertEqual(self.maintenance_settings.days, 7)\n getAdapter(self.portal, IMaintenanceSchema).days = 4\n- self.assertEqual(\n- self.maintenance_settings.days,\n- 4\n- )\n+ self.assertEqual(self.maintenance_settings.days, 4)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_markup_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_markup_adapter.py\nindex 7ec8e09c4e..7c24212ad0 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_markup_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_markup_adapter.py\n@@ -10,13 +10,12 @@\n \n \n class MarkupControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n self.settings = registry.forInterface(IMarkupSchema, prefix="plone")\n \n@@ -24,30 +23,27 @@ def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, IMarkupSchema))\n \n def test_get_default_type(self):\n- self.settings.default_type = \'text/plain\'\n+ self.settings.default_type = "text/plain"\n self.assertEqual(\n- getAdapter(self.portal, IMarkupSchema).default_type,\n- \'text/plain\'\n+ getAdapter(self.portal, IMarkupSchema).default_type, "text/plain"\n )\n \n def test_set_default_type(self):\n- getAdapter(self.portal, IMarkupSchema).default_type = \'text/plain\' # noqa\n- self.assertEqual(\n- self.settings.default_type,\n- \'text/plain\'\n- )\n+ getAdapter(self.portal, IMarkupSchema).default_type = "text/plain" # noqa\n+ self.assertEqual(self.settings.default_type, "text/plain")\n \n def test_get_allowed_types(self):\n- self.settings.allowed_types = (\'text/plain\', \'text/x-web-textile\')\n+ self.settings.allowed_types = ("text/plain", "text/x-web-textile")\n self.assertEqual(\n getAdapter(self.portal, IMarkupSchema).allowed_types,\n- (\'text/plain\', \'text/x-web-textile\')\n+ ("text/plain", "text/x-web-textile"),\n )\n \n def test_set_allowed_types(self):\n- getAdapter(self.portal, IMarkupSchema).allowed_types =\\\n- (\'text/plain\', \'text/x-web-textile\')\n+ getAdapter(self.portal, IMarkupSchema).allowed_types = (\n+ "text/plain",\n+ "text/x-web-textile",\n+ )\n self.assertEqual(\n- self.settings.allowed_types,\n- (\'text/plain\', \'text/x-web-textile\')\n+ self.settings.allowed_types, ("text/plain", "text/x-web-textile")\n )\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_navigation_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_navigation_adapter.py\nindex 819c4a8ebb..4be9b02790 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_navigation_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_navigation_adapter.py\n@@ -10,147 +10,98 @@\n \n \n class NavigationControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n self.navigation_settings = registry.forInterface(\n- INavigationSchema, prefix="plone")\n+ INavigationSchema, prefix="plone"\n+ )\n \n def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, INavigationSchema))\n \n def test_get_generate_tabs(self):\n- self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).generate_tabs,\n- True\n- )\n+ self.assertEqual(getAdapter(self.portal, INavigationSchema).generate_tabs, True)\n self.navigation_settings.generate_tabs = False\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).generate_tabs,\n- False\n+ getAdapter(self.portal, INavigationSchema).generate_tabs, False\n )\n \n def test_set_generate_tabs(self):\n- self.assertEqual(\n- self.navigation_settings.generate_tabs,\n- True\n- )\n+ self.assertEqual(self.navigation_settings.generate_tabs, True)\n getAdapter(self.portal, INavigationSchema).generate_tabs = False\n- self.assertEqual(\n- self.navigation_settings.generate_tabs,\n- False\n- )\n+ self.assertEqual(self.navigation_settings.generate_tabs, False)\n \n def test_get_nonfolderish_tabs(self):\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).nonfolderish_tabs,\n- True\n+ getAdapter(self.portal, INavigationSchema).nonfolderish_tabs, True\n )\n self.navigation_settings.nonfolderish_tabs = False\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).nonfolderish_tabs,\n- False\n+ getAdapter(self.portal, INavigationSchema).nonfolderish_tabs, False\n )\n \n def test_set_nonfolderish_tabs(self):\n- self.assertEqual(\n- self.navigation_settings.nonfolderish_tabs,\n- True\n- )\n+ self.assertEqual(self.navigation_settings.nonfolderish_tabs, True)\n getAdapter(self.portal, INavigationSchema).nonfolderish_tabs = False\n- self.assertEqual(\n- self.navigation_settings.nonfolderish_tabs,\n- False\n- )\n+ self.assertEqual(self.navigation_settings.nonfolderish_tabs, False)\n \n def test_get_displayed_types(self):\n- self.navigation_settings.displayed_types = (\'Folder\',)\n+ self.navigation_settings.displayed_types = ("Folder",)\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).displayed_types,\n- (\'Folder\',)\n+ getAdapter(self.portal, INavigationSchema).displayed_types, ("Folder",)\n )\n \n def test_set_displayed_types(self):\n- getAdapter(\n- self.portal,\n- INavigationSchema\n- ).displayed_types = (\'Folder\',)\n- self.assertEqual(\n- self.navigation_settings.displayed_types,\n- (\'Folder\',)\n- )\n+ getAdapter(self.portal, INavigationSchema).displayed_types = ("Folder",)\n+ self.assertEqual(self.navigation_settings.displayed_types, ("Folder",))\n \n def test_get_filter_on_workflow(self):\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).filter_on_workflow,\n- False\n+ getAdapter(self.portal, INavigationSchema).filter_on_workflow, False\n )\n self.navigation_settings.filter_on_workflow = True\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).filter_on_workflow,\n- True\n+ getAdapter(self.portal, INavigationSchema).filter_on_workflow, True\n )\n \n def test_set_filter_on_workflow(self):\n- self.assertEqual(\n- self.navigation_settings.filter_on_workflow,\n- False\n- )\n+ self.assertEqual(self.navigation_settings.filter_on_workflow, False)\n getAdapter(self.portal, INavigationSchema).filter_on_workflow = True\n- self.assertEqual(\n- self.navigation_settings.filter_on_workflow,\n- True\n- )\n+ self.assertEqual(self.navigation_settings.filter_on_workflow, True)\n \n def test_get_workflow_states_to_show(self):\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).workflow_states_to_show,\n- ()\n+ getAdapter(self.portal, INavigationSchema).workflow_states_to_show, ()\n )\n \n- self.navigation_settings.workflow_states_to_show = (\'private\',)\n+ self.navigation_settings.workflow_states_to_show = ("private",)\n self.assertEqual(\n getAdapter(self.portal, INavigationSchema).workflow_states_to_show,\n- (\'private\',)\n+ ("private",),\n )\n \n def test_set_workflow_states_to_show(self):\n- self.assertEqual(\n- self.navigation_settings.workflow_states_to_show,\n- ()\n- )\n- getAdapter(\n- self.portal,\n- INavigationSchema\n- ).workflow_states_to_show = (\'private\',)\n- self.assertEqual(\n- self.navigation_settings.workflow_states_to_show,\n- (\'private\',)\n+ self.assertEqual(self.navigation_settings.workflow_states_to_show, ())\n+ getAdapter(self.portal, INavigationSchema).workflow_states_to_show = (\n+ "private",\n )\n+ self.assertEqual(self.navigation_settings.workflow_states_to_show, ("private",))\n \n def test_get_show_excluded_items(self):\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).show_excluded_items,\n- False\n+ getAdapter(self.portal, INavigationSchema).show_excluded_items, False\n )\n self.navigation_settings.show_excluded_items = True\n self.assertEqual(\n- getAdapter(self.portal, INavigationSchema).show_excluded_items,\n- True\n+ getAdapter(self.portal, INavigationSchema).show_excluded_items, True\n )\n \n def test_set_show_excluded_items(self):\n- self.assertEqual(\n- self.navigation_settings.show_excluded_items,\n- False\n- )\n+ self.assertEqual(self.navigation_settings.show_excluded_items, False)\n getAdapter(self.portal, INavigationSchema).show_excluded_items = True\n- self.assertEqual(\n- self.navigation_settings.show_excluded_items,\n- True\n- )\n+ self.assertEqual(self.navigation_settings.show_excluded_items, True)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_search_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_search_adapter.py\nindex 28905f2dec..c980f31083 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_search_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_search_adapter.py\n@@ -10,58 +10,40 @@\n \n \n class SearchControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n- self.search_settings = registry.forInterface(\n- ISearchSchema, prefix="plone")\n+ self.search_settings = registry.forInterface(ISearchSchema, prefix="plone")\n \n def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, ISearchSchema))\n \n def test_get_enable_livesearch(self):\n- self.assertEqual(\n- getAdapter(self.portal, ISearchSchema).enable_livesearch,\n- True\n- )\n+ self.assertEqual(getAdapter(self.portal, ISearchSchema).enable_livesearch, True)\n self.search_settings.enable_livesearch = False\n self.assertEqual(\n- getAdapter(self.portal, ISearchSchema).enable_livesearch,\n- False\n+ getAdapter(self.portal, ISearchSchema).enable_livesearch, False\n )\n \n def test_set_enable_livesearch(self):\n- self.assertEqual(\n- self.search_settings.enable_livesearch,\n- True\n- )\n+ self.assertEqual(self.search_settings.enable_livesearch, True)\n getAdapter(self.portal, ISearchSchema).enable_livesearch = False\n- self.assertEqual(\n- self.search_settings.enable_livesearch,\n- False\n- )\n+ self.assertEqual(self.search_settings.enable_livesearch, False)\n \n def test_get_types_not_searched(self):\n self.assertTrue(\n- \'Folder\' not in\n- getAdapter(self.portal, ISearchSchema).types_not_searched\n+ "Folder" not in getAdapter(self.portal, ISearchSchema).types_not_searched\n )\n- self.search_settings.types_not_searched = (\'Folder\',)\n+ self.search_settings.types_not_searched = ("Folder",)\n self.assertTrue(\n- \'Folder\' in\n- getAdapter(self.portal, ISearchSchema).types_not_searched\n+ "Folder" in getAdapter(self.portal, ISearchSchema).types_not_searched\n )\n \n def test_set_types_not_searched(self):\n- self.assertTrue(\n- \'Folder\' not in self.search_settings.types_not_searched\n- )\n- getAdapter(self.portal, ISearchSchema).types_not_searched = (\'Folder\',)\n- self.assertTrue(\n- \'Folder\' in self.search_settings.types_not_searched\n- )\n+ self.assertTrue("Folder" not in self.search_settings.types_not_searched)\n+ getAdapter(self.portal, ISearchSchema).types_not_searched = ("Folder",)\n+ self.assertTrue("Folder" in self.search_settings.types_not_searched)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_security_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_security_adapter.py\nindex 8be6d76154..5e16b2b579 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_security_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_security_adapter.py\n@@ -8,122 +8,67 @@\n \n \n class SecurityControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n self.security_settings = getAdapter(self.portal, ISecuritySchema)\n \n def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, ISecuritySchema))\n \n def test_get_enable_self_reg_setting(self):\n- self.assertEqual(\n- self.security_settings.enable_self_reg,\n- False\n- )\n+ self.assertEqual(self.security_settings.enable_self_reg, False)\n \n def test_set_enable_self_reg_setting(self):\n self.security_settings.enable_self_reg = False\n- self.assertEqual(\n- self.security_settings.enable_self_reg,\n- False\n- )\n+ self.assertEqual(self.security_settings.enable_self_reg, False)\n self.security_settings.enable_self_reg = True\n- self.assertEqual(\n- self.security_settings.enable_self_reg,\n- True\n- )\n+ self.assertEqual(self.security_settings.enable_self_reg, True)\n \n def test_get_enable_user_pwd_choice_setting(self):\n- self.assertEqual(\n- self.security_settings.enable_user_pwd_choice,\n- False\n- )\n+ self.assertEqual(self.security_settings.enable_user_pwd_choice, False)\n \n def test_set_enable_user_pwd_choice_setting(self):\n self.security_settings.enable_user_pwd_choice = False\n- self.assertEqual(\n- self.security_settings.enable_user_pwd_choice,\n- False\n- )\n+ self.assertEqual(self.security_settings.enable_user_pwd_choice, False)\n self.security_settings.enable_user_pwd_choice = True\n- self.assertEqual(\n- self.security_settings.enable_user_pwd_choice,\n- True\n- )\n+ self.assertEqual(self.security_settings.enable_user_pwd_choice, True)\n \n def test_get_enable_user_folders_setting(self):\n- self.assertEqual(\n- self.security_settings.enable_user_folders,\n- False\n- )\n+ self.assertEqual(self.security_settings.enable_user_folders, False)\n \n def test_set_enable_user_folders_setting(self):\n self.security_settings.enable_user_folders = False\n- self.assertEqual(\n- self.security_settings.enable_user_folders,\n- False\n- )\n+ self.assertEqual(self.security_settings.enable_user_folders, False)\n self.security_settings.enable_user_folders = True\n- self.assertEqual(\n- self.security_settings.enable_user_folders,\n- True\n- )\n+ self.assertEqual(self.security_settings.enable_user_folders, True)\n \n def test_get_allow_anon_views_about_setting(self):\n- self.assertEqual(\n- self.security_settings.allow_anon_views_about,\n- False\n- )\n+ self.assertEqual(self.security_settings.allow_anon_views_about, False)\n \n def test_set_allow_anon_views_about_setting(self):\n self.security_settings.allow_anon_views_about = False\n- self.assertEqual(\n- self.security_settings.allow_anon_views_about,\n- False\n- )\n+ self.assertEqual(self.security_settings.allow_anon_views_about, False)\n self.security_settings.allow_anon_views_about = True\n- self.assertEqual(\n- self.security_settings.allow_anon_views_about,\n- True\n- )\n+ self.assertEqual(self.security_settings.allow_anon_views_about, True)\n \n def test_get_use_email_as_login_setting(self):\n- self.assertEqual(\n- self.security_settings.use_email_as_login,\n- False\n- )\n+ self.assertEqual(self.security_settings.use_email_as_login, False)\n \n def test_set_use_email_as_login_setting(self):\n self.security_settings.use_email_as_login = False\n- self.assertEqual(\n- self.security_settings.use_email_as_login,\n- False\n- )\n+ self.assertEqual(self.security_settings.use_email_as_login, False)\n self.security_settings.use_email_as_login = True\n- self.assertEqual(\n- self.security_settings.use_email_as_login,\n- True\n- )\n+ self.assertEqual(self.security_settings.use_email_as_login, True)\n \n def test_get_use_uuid_as_userid_setting(self):\n- self.assertEqual(\n- self.security_settings.use_uuid_as_userid,\n- False\n- )\n+ self.assertEqual(self.security_settings.use_uuid_as_userid, False)\n \n def test_set_use_uuid_as_userid_setting(self):\n self.security_settings.use_uuid_as_userid = False\n- self.assertEqual(\n- self.security_settings.use_uuid_as_userid,\n- False\n- )\n+ self.assertEqual(self.security_settings.use_uuid_as_userid, False)\n self.security_settings.use_uuid_as_userid = True\n- self.assertEqual(\n- self.security_settings.use_uuid_as_userid,\n- True\n- )\n+ self.assertEqual(self.security_settings.use_uuid_as_userid, True)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_site_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_site_adapter.py\nindex 5901222888..1f5f2e9a6e 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_site_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_site_adapter.py\n@@ -10,13 +10,12 @@\n \n \n class SiteControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n self.settings = registry.forInterface(ISiteSchema, prefix="plone")\n \n@@ -24,43 +23,25 @@ def test_adapter_lookup(self):\n self.assertTrue(getAdapter(self.portal, ISiteSchema))\n \n def test_get_site_title(self):\n- self.settings.site_title = \'Great Site\'\n- self.assertEqual(\n- getAdapter(self.portal, ISiteSchema).site_title,\n- \'Great Site\'\n- )\n+ self.settings.site_title = "Great Site"\n+ self.assertEqual(getAdapter(self.portal, ISiteSchema).site_title, "Great Site")\n \n def test_set_site_title(self):\n- getAdapter(self.portal, ISiteSchema).site_title = \'Good Site\'\n- self.assertEqual(\n- self.settings.site_title,\n- \'Good Site\'\n- )\n+ getAdapter(self.portal, ISiteSchema).site_title = "Good Site"\n+ self.assertEqual(self.settings.site_title, "Good Site")\n \n def test_set_site_title_string(self):\n- getAdapter(self.portal, ISiteSchema).site_title = \'Good Site\'\n- self.assertEqual(\n- self.settings.site_title,\n- \'Good Site\'\n- )\n+ getAdapter(self.portal, ISiteSchema).site_title = "Good Site"\n+ self.assertEqual(self.settings.site_title, "Good Site")\n \n def test_get_webstats_js(self):\n- self.settings.webstats_js = \'Script Tag\'\n- self.assertEqual(\n- getAdapter(self.portal, ISiteSchema).webstats_js,\n- \'Script Tag\'\n- )\n+ self.settings.webstats_js = "Script Tag"\n+ self.assertEqual(getAdapter(self.portal, ISiteSchema).webstats_js, "Script Tag")\n \n def test_set_webstats_js(self):\n- getAdapter(self.portal, ISiteSchema).webstats_js = \'Script Tag\'\n- self.assertEqual(\n- self.settings.webstats_js,\n- \'Script Tag\'\n- )\n+ getAdapter(self.portal, ISiteSchema).webstats_js = "Script Tag"\n+ self.assertEqual(self.settings.webstats_js, "Script Tag")\n \n def test_set_webstats_js_string(self):\n- getAdapter(self.portal, ISiteSchema).webstats_js = \'Script Tag\'\n- self.assertEqual(\n- self.settings.webstats_js,\n- \'Script Tag\'\n- )\n+ getAdapter(self.portal, ISiteSchema).webstats_js = "Script Tag"\n+ self.assertEqual(self.settings.webstats_js, "Script Tag")\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_usergroups_adapter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_usergroups_adapter.py\nindex 7140b64110..c99edf9000 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_usergroups_adapter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_bbb_usergroups_adapter.py\n@@ -10,33 +10,28 @@\n \n \n class UserGroupsControlPanelAdapterTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n self.usergroups_settings = registry.forInterface(\n- IUserGroupsSettingsSchema, prefix="plone")\n+ IUserGroupsSettingsSchema, prefix="plone"\n+ )\n \n def test_adapter_lookup(self):\n- self.assertTrue(\n- getAdapter(self.portal, IUserGroupsSettingsSchema)\n- )\n+ self.assertTrue(getAdapter(self.portal, IUserGroupsSettingsSchema))\n \n def test_many_groups(self):\n getAdapter(self.portal, IUserGroupsSettingsSchema).set_many_groups(True)\n self.assertEqual(\n- getAdapter(\n- self.portal, IUserGroupsSettingsSchema).get_many_groups(),\n- True\n+ getAdapter(self.portal, IUserGroupsSettingsSchema).get_many_groups(), True\n )\n \n def test_many_users(self):\n getAdapter(self.portal, IUserGroupsSettingsSchema).set_many_users(True)\n self.assertEqual(\n- getAdapter(self.portal, IUserGroupsSettingsSchema).get_many_users(),\n- True\n+ getAdapter(self.portal, IUserGroupsSettingsSchema).get_many_users(), True\n )\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_editing.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_editing.py\nindex 2157771f56..f89b45c258 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_editing.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_editing.py\n@@ -18,48 +18,41 @@ class EditingControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.request = self.layer[\'request\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.request = self.layer["request"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n \n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(IEditingSchema, prefix=\'plone\')\n+ self.settings = registry.forInterface(IEditingSchema, prefix="plone")\n \n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_editing_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Editing\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Editing").click()\n \n def test_editing_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@editing-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@editing-controlpanel" % self.portal_url)\n self.assertTrue("Content" in self.browser.contents)\n \n def test_editing_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@editing-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@editing-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n @unittest.skip("TODO: Not implemented yet.")\n def test_visible_ids_active(self):\n pass\n \n def test_default_editor(self):\n- self.browser.open(\n- "%s/@@editing-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@editing-controlpanel" % self.portal_url)\n self.browser.getControl("Default editor").value = ["None"]\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.default_editor, "None")\n \n@@ -68,16 +61,13 @@ def test_default_editor_active(self):\n pass\n \n def test_available_editors_hidden(self):\n- self.browser.open(\n- "%s/@@editing-controlpanel" % self.portal_url)\n- self.assertTrue(\'Available editors\' not in self.browser.contents)\n+ self.browser.open("%s/@@editing-controlpanel" % self.portal_url)\n+ self.assertTrue("Available editors" not in self.browser.contents)\n \n def test_ext_editor(self):\n- self.browser.open(\n- "%s/@@editing-controlpanel" % self.portal_url)\n- self.browser.getControl("Enable External Editor feature")\\\n- .selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@editing-controlpanel" % self.portal_url)\n+ self.browser.getControl("Enable External Editor feature").selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.ext_editor, True)\n \n@@ -86,28 +76,24 @@ def test_ext_editor_active(self):\n pass\n \n def test_enable_link_integrity_checks(self):\n- self.browser.open(\n- "%s/@@editing-controlpanel" % self.portal_url)\n- self.browser.getControl("Enable link integrity checks")\\\n- .selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@editing-controlpanel" % self.portal_url)\n+ self.browser.getControl("Enable link integrity checks").selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.enable_link_integrity_checks, True)\n \n def test_enable_link_integrity_checks_active(self):\n- self.browser.open(\n- "%s/@@editing-controlpanel" % self.portal_url)\n- self.browser.getControl("Enable link integrity checks")\\\n- .selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@editing-controlpanel" % self.portal_url)\n+ self.browser.getControl("Enable link integrity checks").selected = True\n+ self.browser.getControl("Save").click()\n self.assertTrue(linkintegrity_enabled())\n \n def test_lock_on_ttw_edit(self):\n- self.browser.open(\n- "%s/@@editing-controlpanel" % self.portal_url)\n- self.browser.getControl("Enable locking for through-the-web edits")\\\n- .selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@editing-controlpanel" % self.portal_url)\n+ self.browser.getControl(\n+ "Enable locking for through-the-web edits"\n+ ).selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.lock_on_ttw_edit, True)\n \ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_error_log.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_error_log.py\nindex 2ec0ca1b1b..af3ba9975f 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_error_log.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_error_log.py\n@@ -8,16 +8,15 @@\n \n \n class ErrorLogControlPanelFunctionalTest(unittest.TestCase):\n- """Test for Controlpanel Error Log\n- """\n+ """Test for Controlpanel Error Log"""\n \n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n error_log_properties = None\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.request = self.layer[\'request\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.request = self.layer["request"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n \n # keep initial error_log_properties to reset them\n@@ -26,39 +25,46 @@ def setUp(self):\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def tearDown(self):\n # reset error log properties\n- keep_entries = self.error_log_properties[\'keep_entries\']\n- copy_to_zlog = self.error_log_properties[\'copy_to_zlog\']\n- ignored_exceptions = self.error_log_properties[\'ignored_exceptions\']\n- self.portal.error_log.setProperties(keep_entries, copy_to_zlog, ignored_exceptions)\n+ keep_entries = self.error_log_properties["keep_entries"]\n+ copy_to_zlog = self.error_log_properties["copy_to_zlog"]\n+ ignored_exceptions = self.error_log_properties["ignored_exceptions"]\n+ self.portal.error_log.setProperties(\n+ keep_entries, copy_to_zlog, ignored_exceptions\n+ )\n \n def test_error_log_control_panel_link(self):\n self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Errors\').click()\n+ self.browser.getLink("Errors").click()\n \n self.assertEqual(self.browser.url, "%s/@@error-log-form" % self.portal_url)\n- self.assertIn(\'Error log \', self.browser.contents)\n+ self.assertIn("Error log ", self.browser.contents)\n \n def test_error_log_set_properties(self):\n- self.assertEqual(self.error_log_properties[\'keep_entries\'], 20)\n- self.assertEqual(self.error_log_properties[\'copy_to_zlog\'], True)\n- self.assertEqual(self.error_log_properties[\'ignored_exceptions\'], (\'Unauthorized\', \'NotFound\', \'Redirect\'))\n+ self.assertEqual(self.error_log_properties["keep_entries"], 20)\n+ self.assertEqual(self.error_log_properties["copy_to_zlog"], True)\n+ self.assertEqual(\n+ self.error_log_properties["ignored_exceptions"],\n+ ("Unauthorized", "NotFound", "Redirect"),\n+ )\n \n self.request.form = {\n- \'keep_entries\': 40,\n- \'ignored_exceptions\': [\'NotFound\', \'Redirect\']\n+ "keep_entries": 40,\n+ "ignored_exceptions": ["NotFound", "Redirect"],\n }\n \n- set_properties_view = getMultiAdapter((self.portal, self.request),\n- name=\'error-log-set-properties\')\n+ set_properties_view = getMultiAdapter(\n+ (self.portal, self.request), name="error-log-set-properties"\n+ )\n set_properties_view()\n \n error_log_properties = self.portal.error_log.getProperties()\n- self.assertEqual(error_log_properties[\'keep_entries\'], 40)\n- self.assertEqual(error_log_properties[\'copy_to_zlog\'], False)\n- self.assertEqual(error_log_properties[\'ignored_exceptions\'], (\'NotFound\', \'Redirect\'))\n+ self.assertEqual(error_log_properties["keep_entries"], 40)\n+ self.assertEqual(error_log_properties["copy_to_zlog"], False)\n+ self.assertEqual(\n+ error_log_properties["ignored_exceptions"], ("NotFound", "Redirect")\n+ )\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_filter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_filter.py\nindex 60eb00aaf8..bc5b57ae1a 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_filter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_filter.py\n@@ -20,90 +20,74 @@ class FilterControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n self.portal_url = self.portal.absolute_url()\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- IFilterSchema, prefix="plone")\n+ self.settings = registry.forInterface(IFilterSchema, prefix="plone")\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n self.safe_html = getattr(\n- getToolByName(self.portal, \'portal_transforms\'),\n- \'safe_html\',\n- None)\n+ getToolByName(self.portal, "portal_transforms"), "safe_html", None\n+ )\n \n def test_filter_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site").click()\n \n def test_filter_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@filter-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@filter-controlpanel" % self.portal_url)\n self.assertTrue("Security" in self.browser.contents)\n \n def test_filter_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@filter-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@filter-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_filter_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="filter-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="filter-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_disable_filtering(self):\n- self.browser.open(\n- "%s/@@filter-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@filter-controlpanel" % self.portal_url)\n self.browser.getControl(\n- name=\'form.widgets.disable_filtering:list\').value = "selected"\n- self.browser.getControl(\'Save\').click()\n+ name="form.widgets.disable_filtering:list"\n+ ).value = "selected"\n+ self.browser.getControl("Save").click()\n \n # test that the transform is disabled\n- self.assertEqual(\n- self.settings.disable_filtering,\n- 1)\n+ self.assertEqual(self.settings.disable_filtering, 1)\n \n # anything passes\n- nasty_html = \'\'\n- ds = datastream(\'dummy_name\')\n- self.assertEqual(\n- nasty_html,\n- str(self.safe_html.convert(nasty_html, ds))\n- )\n+ nasty_html = ""\n+ ds = datastream("dummy_name")\n+ self.assertEqual(nasty_html, str(self.safe_html.convert(nasty_html, ds)))\n \n def test_nasty_tags(self):\n- self.browser.open(\n- "%s/@@filter-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@filter-controlpanel" % self.portal_url)\n self.assertEqual(\n- self.browser.getControl(name=\'form.widgets.nasty_tags\').value,\n- \'style\\nobject\\nembed\\napplet\\nscript\\nmeta\')\n- self.browser.getControl(\n- name=\'form.widgets.nasty_tags\').value = \'div\\na\'\n- valid_tags = self.browser.getControl(\n- name=\'form.widgets.valid_tags\').value\n- self.assertTrue(valid_tags.startswith(\'a\\nabbr\\nacronym\\naddress\'))\n- valid_tags = valid_tags.replace(\'a\\n\', \'\')\n+ self.browser.getControl(name="form.widgets.nasty_tags").value,\n+ "style\\nobject\\nembed\\napplet\\nscript\\nmeta",\n+ )\n+ self.browser.getControl(name="form.widgets.nasty_tags").value = "div\\na"\n+ valid_tags = self.browser.getControl(name="form.widgets.valid_tags").value\n+ self.assertTrue(valid_tags.startswith("a\\nabbr\\nacronym\\naddress"))\n+ valid_tags = valid_tags.replace("a\\n", "")\n valid_tags = self.browser.getControl(\n- name=\'form.widgets.valid_tags\').value = valid_tags\n- self.browser.getControl(\'Save\').click()\n- self.assertEqual(self.settings.nasty_tags, [\'div\', \'a\'])\n- self.assertNotIn(\'a\', self.settings.valid_tags)\n+ name="form.widgets.valid_tags"\n+ ).value = valid_tags\n+ self.browser.getControl("Save").click()\n+ self.assertEqual(self.settings.nasty_tags, ["div", "a"])\n+ self.assertNotIn("a", self.settings.valid_tags)\n \n # test that is filtered\n self.assertFalse(self.settings.disable_filtering)\n good_html = \'harmless link
\'\n- ds = datastream(\'dummy_name\')\n- self.assertEqual(\n- self.safe_html.convert(good_html, ds).getData(),\n- \'
\'\n- )\n+ ds = datastream("dummy_name")\n+ self.assertEqual(self.safe_html.convert(good_html, ds).getData(), "
")\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_installer.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_installer.py\nindex 67192a3a60..214b2e95ed 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_installer.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_installer.py\n@@ -13,71 +13,62 @@ class AddonsControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_addons_controlpanel_link(self):\n- self.browser.open(\n- \'%s/@@overview-controlpanel\' % self.portal_url)\n- self.browser.getLink(\'Add-ons\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Add-ons").click()\n \n def test_addons_controlpanel_backlink(self):\n- self.browser.open(\n- \'%s/prefs_install_products_form\' % self.portal_url)\n- self.assertTrue(\'General\' in self.browser.contents)\n+ self.browser.open("%s/prefs_install_products_form" % self.portal_url)\n+ self.assertTrue("General" in self.browser.contents)\n \n def test_addons_controlpanel_sidebar(self):\n- self.browser.open(\n- \'%s/prefs_install_products_form\' % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/prefs_install_products_form" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_addons_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name=\'prefs_install_products_form\')\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="prefs_install_products_form"\n+ )\n self.assertTrue(view())\n \n def test_addons_controlpanel_no_upgrades(self):\n- self.browser.open(\n- \'%s/prefs_install_products_form\' % self.portal_url)\n- self.assertIn(\'No upgrades in this corner\', self.browser.contents)\n+ self.browser.open("%s/prefs_install_products_form" % self.portal_url)\n+ self.assertIn("No upgrades in this corner", self.browser.contents)\n \n def test_addons_controlpanel_installable(self):\n- self.browser.open(\n- \'%s/prefs_install_products_form\' % self.portal_url)\n+ self.browser.open("%s/prefs_install_products_form" % self.portal_url)\n # We expect a few standard add-ons.\n- self.assertIn(\'Workflow Policy Support\', self.browser.contents)\n- self.assertIn(\'Multilingual Support\', self.browser.contents)\n- self.assertIn(\'plone.session\', self.browser.contents)\n+ self.assertIn("Workflow Policy Support", self.browser.contents)\n+ self.assertIn("Multilingual Support", self.browser.contents)\n+ self.assertIn("plone.session", self.browser.contents)\n \n def test_addons_controlpanel_not_installable(self):\n- self.browser.open(\n- \'%s/prefs_install_products_form\' % self.portal_url)\n+ self.browser.open("%s/prefs_install_products_form" % self.portal_url)\n # We do not expect some other add-ons.\n- self.assertNotIn(\'plone.app.upgrade\', self.browser.contents)\n- self.assertNotIn(\'Products.CMFPlone\', self.browser.contents)\n+ self.assertNotIn("plone.app.upgrade", self.browser.contents)\n+ self.assertNotIn("Products.CMFPlone", self.browser.contents)\n \n def test_addons_controlpanel_install_and_uninstall_all(self):\n- self.browser.open(\n- \'%s/prefs_install_products_form\' % self.portal_url)\n- self.assertNotIn(\'Installed\', self.browser.contents)\n- self.assertNotIn(\'Uninstalled\', self.browser.contents)\n+ self.browser.open("%s/prefs_install_products_form" % self.portal_url)\n+ self.assertNotIn("Installed", self.browser.contents)\n+ self.assertNotIn("Uninstalled", self.browser.contents)\n \n # In a fresh site there should be no uninstall buttons.\n # If there is one, it is likely an upgrade profile that should be hidden.\n # This could change: we might for example install a theme by default\n # but make it uninstallable. The logic in this test should be updated then.\n try:\n- button = self.browser.getControl(\'Uninstall\', index=0)\n+ button = self.browser.getControl("Uninstall", index=0)\n except LookupError:\n # This is good.\n pass\n@@ -93,29 +84,29 @@ def test_addons_controlpanel_install_and_uninstall_all(self):\n # We install all available products.\n for buttons in range(12):\n try:\n- self.browser.getControl(\'Install\', index=buttons)\n+ self.browser.getControl("Install", index=buttons)\n except LookupError:\n break\n else:\n # Either our test logic is off, or the code that determines\n # which products are installable is actually wrong.\n- raise AssertionError(\'Too many Install buttons.\')\n+ raise AssertionError("Too many Install buttons.")\n # Click all install buttons.\n for button in range(buttons):\n # Always install the first.\n- self.browser.getControl(\'Install\', index=0).click()\n- self.assertIn(\'Installed\', self.browser.contents)\n+ self.browser.getControl("Install", index=0).click()\n+ self.assertIn("Installed", self.browser.contents)\n # There are no more install buttons.\n with self.assertRaises(LookupError):\n- self.browser.getControl(\'Install\', index=0)\n+ self.browser.getControl("Install", index=0)\n # There should now be just as many Uninstall buttons.\n- self.browser.getControl(\'Uninstall\', index=buttons - 1)\n+ self.browser.getControl("Uninstall", index=buttons - 1)\n for button in range(buttons):\n # Always uninstall the first.\n- self.browser.getControl(\'Uninstall\', index=0).click()\n- self.assertIn(\'Uninstalled\', self.browser.contents)\n+ self.browser.getControl("Uninstall", index=0).click()\n+ self.assertIn("Uninstalled", self.browser.contents)\n # There are no more uninstall buttons.\n with self.assertRaises(LookupError):\n- self.browser.getControl(\'Uninstall\', index=0)\n+ self.browser.getControl("Uninstall", index=0)\n # Instead, we could install all again if we want.\n- self.browser.getControl(\'Install\', index=buttons - 1)\n+ self.browser.getControl("Install", index=buttons - 1)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_language.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_language.py\nindex 35ebc885fc..cf137ed88a 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_language.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_language.py\n@@ -19,70 +19,57 @@ class LanguageControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def _inject_available_languages_field(self, value):\n """The in-and-out widget does not work without javascript, therefore\n- we have to inject some values in order to make saving the form work.\n+ we have to inject some values in order to make saving the form work.\n """\n- form = self.browser.getForm(id=\'LanguageControlPanel\')\n- name = \'form.widgets.available_languages:list\'\n- field = webtest.forms.Hidden(form._form, \'input\', name, 0, value=value)\n+ form = self.browser.getForm(id="LanguageControlPanel")\n+ name = "form.widgets.available_languages:list"\n+ field = webtest.forms.Hidden(form._form, "input", name, 0, value=value)\n form._form.field_order.append((name, field))\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl("Save").click()\n \n def test_language_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Language\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Language").click()\n self.assertTrue("Language Settings" in self.browser.contents)\n \n def test_language_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertTrue("General" in self.browser.contents)\n \n def test_language_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_language_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="language-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="language-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_default_language(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n- self.assertEqual(settings.default_language, \'en\')\n- self.assertEqual(\n- self.browser.getControl(\n- \'Site language\'\n- ).value,\n- [\'en\']\n- )\n- self.browser.getControl(\n- \'Site language\'\n- ).value = [\'de\']\n- self._inject_available_languages_field(\'en\')\n- self._inject_available_languages_field(\'de\')\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n+ self.assertEqual(settings.default_language, "en")\n+ self.assertEqual(self.browser.getControl("Site language").value, ["en"])\n+ self.browser.getControl("Site language").value = ["de"]\n+ self._inject_available_languages_field("en")\n+ self._inject_available_languages_field("de")\n+ self.browser.getControl(name="form.buttons.save").click()\n \n- self.assertEqual(settings.default_language, \'de\')\n+ self.assertEqual(settings.default_language, "de")\n \n # def test_available_languages(self):\n # registry = getUtility(IRegistry)\n@@ -105,191 +92,148 @@ def test_default_language(self):\n def test_use_combined_language_codes(self):\n """This checks swithing combined languages codes support off/on."""\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.use_combined_language_codes, True)\n self.assertEqual(\n- self.browser.getControl(\n- \'Show country-specific language variants\'\n- ).selected,\n- True\n+ self.browser.getControl("Show country-specific language variants").selected,\n+ True,\n )\n self.browser.getControl(\n- \'Show country-specific language variants\'\n+ "Show country-specific language variants"\n ).selected = False\n \n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.use_combined_language_codes, False)\n \n def test_display_flags(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.display_flags, False)\n- self.assertEqual(\n- self.browser.getControl(\n- \'Show language flags\'\n- ).selected,\n- False\n- )\n- self.browser.getControl(\n- \'Show language flags\'\n- ).selected = True\n+ self.assertEqual(self.browser.getControl("Show language flags").selected, False)\n+ self.browser.getControl("Show language flags").selected = True\n \n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.display_flags, True)\n \n def test_use_content_negotiation(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.use_content_negotiation, False)\n self.assertEqual(\n- self.browser.getControl(\n- \'Use the language of the content item\'\n- ).selected,\n- False\n+ self.browser.getControl("Use the language of the content item").selected,\n+ False,\n )\n- self.browser.getControl(\n- \'Use the language of the content item\'\n- ).selected = True\n+ self.browser.getControl("Use the language of the content item").selected = True\n \n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.use_content_negotiation, True)\n \n def test_use_path_negotiation(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.use_path_negotiation, False)\n self.assertEqual(\n self.browser.getControl(\n- \'Use language codes in URL path for manual override\'\n+ "Use language codes in URL path for manual override"\n ).selected,\n- False\n+ False,\n )\n self.browser.getControl(\n- \'Use language codes in URL path for manual override\'\n+ "Use language codes in URL path for manual override"\n ).selected = True\n \n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.use_path_negotiation, True)\n \n def test_use_cookie_negotiation(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.use_cookie_negotiation, False)\n self.assertEqual(\n- self.browser.getControl(\n- \'Use cookie for manual override\'\n- ).selected,\n- False\n+ self.browser.getControl("Use cookie for manual override").selected, False\n )\n- self.browser.getControl(\n- \'Use cookie for manual override\'\n- ).selected = True\n+ self.browser.getControl("Use cookie for manual override").selected = True\n \n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.use_cookie_negotiation, True)\n \n def test_authenticated_users_only(self):\n control_label = "Authenticated users only"\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.authenticated_users_only, False)\n- self.assertEqual(\n- self.browser.getControl(control_label).selected,\n- False\n- )\n+ self.assertEqual(self.browser.getControl(control_label).selected, False)\n self.browser.getControl(control_label).selected = True\n \n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.authenticated_users_only, True)\n \n def test_set_cookie_always(self):\n control_label = "Set the language cookie always"\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.set_cookie_always, False)\n- self.assertEqual(\n- self.browser.getControl(control_label).selected,\n- False\n- )\n+ self.assertEqual(self.browser.getControl(control_label).selected, False)\n self.browser.getControl(control_label).selected = True\n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.set_cookie_always, True)\n \n def test_use_subdomain_negotiation(self):\n control_label = "Use subdomain"\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.use_subdomain_negotiation, False)\n- self.assertEqual(\n- self.browser.getControl(control_label).selected,\n- False\n- )\n+ self.assertEqual(self.browser.getControl(control_label).selected, False)\n self.browser.getControl(control_label).selected = True\n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.use_subdomain_negotiation, True)\n \n def test_use_cctld_negotiation(self):\n control_label = "Use top-level domain"\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.use_cctld_negotiation, False)\n- self.assertEqual(\n- self.browser.getControl(control_label).selected,\n- False\n- )\n+ self.assertEqual(self.browser.getControl(control_label).selected, False)\n self.browser.getControl(control_label).selected = True\n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.use_cctld_negotiation, True)\n \n def test_use_request_negotiation(self):\n control_label = "Use browser language request negotiation"\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ILanguageSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@language-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(ILanguageSchema, prefix="plone")\n+ self.browser.open("%s/@@language-controlpanel" % self.portal_url)\n self.assertEqual(settings.use_request_negotiation, False)\n- self.assertEqual(\n- self.browser.getControl(control_label).selected,\n- False\n- )\n+ self.assertEqual(self.browser.getControl(control_label).selected, False)\n self.browser.getControl(control_label).selected = True\n- self._inject_available_languages_field(\'en\')\n- self.browser.getControl(\'Save\').click()\n+ self._inject_available_languages_field("en")\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.use_request_negotiation, True)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_mail.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_mail.py\nindex 23b62dec2f..67fb796f9d 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_mail.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_mail.py\n@@ -18,194 +18,164 @@ class MailControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_mail_controlpanel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Mail\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Mail").click()\n \n def test_mail_controlpanel_backlink(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n self.assertTrue("General" in self.browser.contents)\n \n def test_mail_controlpanel_sidebar(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_mail_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="mail-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="mail-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_mail_controlpanel_smtp_host(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.smtp_host\').value = \'example.com\'\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.smtp_host").value = "example.com"\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n- self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(IMailSchema, prefix="plone")\n- self.assertEqual(settings.smtp_host, \'example.com\')\n+ self.assertEqual(settings.smtp_host, "example.com")\n \n def test_mail_controlpanel_smtp_port(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.smtp_port\').value = \'88\'\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.smtp_port").value = "88"\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n- self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(IMailSchema, prefix="plone")\n- self.assertEqual(str(settings.smtp_port), \'88\')\n+ self.assertEqual(str(settings.smtp_port), "88")\n \n def test_mail_controlpanel_smtp_userid(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.smtp_userid\').value = \'john@example.com\'\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n+ name="form.widgets.smtp_userid"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(IMailSchema, prefix="plone")\n- self.assertEqual(settings.smtp_userid, \'john@example.com\')\n+ self.assertEqual(settings.smtp_userid, "john@example.com")\n \n def test_mail_controlpanel_smtp_pass(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.smtp_pass").value = "secret"\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.smtp_pass\').value = \'secret\'\n- self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n- self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(IMailSchema, prefix="plone")\n- self.assertEqual(settings.smtp_pass, \'secret\')\n+ self.assertEqual(settings.smtp_pass, "secret")\n \n def test_mail_controlpanel_smtp_pass_keep_on_saving(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.smtp_userid\').value = \'john@example.com\'\n- self.browser.getControl(\n- name=\'form.widgets.smtp_pass\').value = \'secret\'\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n+ name="form.widgets.smtp_userid"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.widgets.smtp_pass").value = "secret"\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n+ self.browser.getControl(name="form.buttons.save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(IMailSchema, prefix="plone")\n- self.assertEqual(settings.smtp_pass, \'secret\')\n+ self.assertEqual(settings.smtp_pass, "secret")\n \n def test_mail_controlpanel_email_from_name(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n- self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(IMailSchema, prefix="plone")\n- self.assertEqual(settings.email_from_name, \'John\')\n+ self.assertEqual(settings.email_from_name, "John")\n \n def test_mail_controlpanel_email_from_address(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(IMailSchema, prefix="plone")\n- self.assertEqual(settings.email_from_address, \'john@example.com\')\n+ self.assertEqual(settings.email_from_address, "john@example.com")\n \n def test_mail_controlpanel_contactinfo_page(self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n- self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n \n- self.browser.open(\n- "%s/contact-info" % self.portal_url)\n+ self.browser.open("%s/contact-info" % self.portal_url)\n self.assertTrue(\n- \'Message\' in self.browser.contents,\n- \'Message exists not in the contact-info form!\'\n+ "Message" in self.browser.contents,\n+ "Message exists not in the contact-info form!",\n )\n \n- def test_controlpanel_overview_shows_no_unconfigured_mailhost_warning(\n- self):\n- self.browser.open(\n- "%s/@@mail-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.email_from_name\').value = \'John\'\n+ def test_controlpanel_overview_shows_no_unconfigured_mailhost_warning(self):\n+ self.browser.open("%s/@@mail-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.email_from_name").value = "John"\n self.browser.getControl(\n- name=\'form.widgets.email_from_address\').value = \\\n- \'john@example.com\'\n- self.browser.getControl(name=\'form.buttons.save\').click()\n+ name="form.widgets.email_from_address"\n+ ).value = "john@example.com"\n+ self.browser.getControl(name="form.buttons.save").click()\n \n- self.browser.open(\n- "%s/overview-controlpanel" % self.portal_url)\n+ self.browser.open("%s/overview-controlpanel" % self.portal_url)\n self.assertFalse(\n- \'not configured a mail host\' in self.browser.contents,\n- \'There should not be a warning for unconfigured mailhost!\'\n+ "not configured a mail host" in self.browser.contents,\n+ "There should not be a warning for unconfigured mailhost!",\n )\n \n- def test_controlpanel_overview_shows_unconfigured_mailhost_warning(\n- self):\n+ def test_controlpanel_overview_shows_unconfigured_mailhost_warning(self):\n registry = getUtility(IRegistry)\n settings = registry.forInterface(IMailSchema, prefix="plone")\n settings.email_from_name = None\n settings.email_from_address = None\n- self.browser.open(\n- "%s/overview-controlpanel" % self.portal_url)\n+ self.browser.open("%s/overview-controlpanel" % self.portal_url)\n self.assertTrue(\n- \'not configured a mail host\' in self.browser.contents,\n- \'There should be a warning for unconfigured mailhost!\'\n+ "not configured a mail host" in self.browser.contents,\n+ "There should be a warning for unconfigured mailhost!",\n )\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_maintenance.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_maintenance.py\nindex c8add25703..2dc5de75bb 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_maintenance.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_maintenance.py\n@@ -9,7 +9,7 @@\n import unittest\n \n \n-has_zope4 = get_distribution(\'Zope2\').version.startswith(\'4\')\n+has_zope4 = get_distribution("Zope2").version.startswith("4")\n \n \n class MaintenanceControlPanelFunctionalTest(unittest.TestCase):\n@@ -20,71 +20,68 @@ class MaintenanceControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.request = self.layer[\'request\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.request = self.layer["request"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n # we have to create a user on the zope root. this just does not work\n # with plone.app.testing and TEST_USER or SITE_OWNER\n- self.app.acl_users.userFolderAddUser(\'app\', TEST_USER_PASSWORD, [\'Manager\'], [])\n- login(self.app[\'acl_users\'], \'app\')\n+ self.app.acl_users.userFolderAddUser("app", TEST_USER_PASSWORD, ["Manager"], [])\n+ login(self.app["acl_users"], "app")\n \n import transaction\n+\n transaction.commit()\n self.browser.addHeader(\n- \'Authorization\',\n- \'Basic {}:{}\'.format(\'app\', TEST_USER_PASSWORD)\n+ "Authorization", "Basic {}:{}".format("app", TEST_USER_PASSWORD)\n )\n \n self.site_administrator_browser = Browser(self.app)\n self.site_administrator_browser.handleErrors = False\n self.site_administrator_browser.addHeader(\n- \'Authorization\',\n- f\'Basic {TEST_USER_NAME}:{TEST_USER_PASSWORD}\'\n+ "Authorization", f"Basic {TEST_USER_NAME}:{TEST_USER_PASSWORD}"\n )\n \n def test_maintenance_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Editing\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Editing").click()\n \n def test_maintenance_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@maintenance-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@maintenance-controlpanel" % self.portal_url)\n self.assertTrue("Advanced" in self.browser.contents)\n \n def test_maintenance_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@maintenance-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@maintenance-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_maintenance_control_panel_raises_unauthorized(self):\n self.site_administrator_browser.open(\n- self.portal_url + \'/@@maintenance-controlpanel\')\n+ self.portal_url + "/@@maintenance-controlpanel"\n+ )\n self.assertTrue(\n- \'You are not allowed to manage the Zope server.\'\n- in self.site_administrator_browser.contents)\n+ "You are not allowed to manage the Zope server."\n+ in self.site_administrator_browser.contents\n+ )\n \n def test_maintenance_pack_database(self):\n """While we cannot test the actual packaging during tests, we can skip\n- the actual manage_pack method by providing a negative value for\n- days.\n+ the actual manage_pack method by providing a negative value for\n+ days.\n """\n- self.browser.open(self.portal_url + \'/@@maintenance-controlpanel\')\n+ self.browser.open(self.portal_url + "/@@maintenance-controlpanel")\n db = self.portal._p_jar.db()\n original_pack = db.pack\n \n def pack(self, t=None, days=0):\n pass\n+\n db.pack = pack\n \n- self.browser.getControl(name=\'form.widgets.days\').value = \'0\'\n+ self.browser.getControl(name="form.widgets.days").value = "0"\n self.browser.getControl(name="form.buttons.pack").click()\n- self.assertTrue(self.browser.url.endswith(\'maintenance-controlpanel\'))\n- self.assertTrue(\'Packed the database.\' in self.browser.contents)\n+ self.assertTrue(self.browser.url.endswith("maintenance-controlpanel"))\n+ self.assertTrue("Packed the database." in self.browser.contents)\n db.pack = original_pack\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_markup.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_markup.py\nindex 8436d3fb3f..18b726dc32 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_markup.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_markup.py\n@@ -18,87 +18,80 @@ class MarkupControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_markup_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Markup\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Markup").click()\n \n def test_markup_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@markup-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@markup-controlpanel" % self.portal_url)\n self.assertTrue("Content" in self.browser.contents)\n \n def test_markup_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@markup-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@markup-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_markup_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="markup-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="markup-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_default_type(self):\n- self.browser.open(\n- "%s/@@markup-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Default format\').value = [\'text/plain\']\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@markup-controlpanel" % self.portal_url)\n+ self.browser.getControl("Default format").value = ["text/plain"]\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n- settings = registry.forInterface(IMarkupSchema, prefix=\'plone\')\n- self.assertEqual(settings.default_type, \'text/plain\')\n+ settings = registry.forInterface(IMarkupSchema, prefix="plone")\n+ self.assertEqual(settings.default_type, "text/plain")\n \n def test_allowed_types(self):\n- self.browser.open(\n- "%s/@@markup-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.allowed_types:list\'\n- ).value = [\'text/html\', \'text/x-web-textile\']\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@markup-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.allowed_types:list").value = [\n+ "text/html",\n+ "text/x-web-textile",\n+ ]\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n- settings = registry.forInterface(IMarkupSchema, prefix=\'plone\')\n- self.assertEqual(settings.allowed_types,\n- (\'text/html\', \'text/x-web-textile\'))\n+ settings = registry.forInterface(IMarkupSchema, prefix="plone")\n+ self.assertEqual(settings.allowed_types, ("text/html", "text/x-web-textile"))\n \n def test_markdown_extensions(self):\n- self.browser.open(\n- "%s/@@markup-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@markup-controlpanel" % self.portal_url)\n self.assertEqual(\n- self.browser.getControl(\n- name=\'form.widgets.markdown_extensions\'\n- ).value,\n- \'markdown.extensions.fenced_code\\nmarkdown.extensions.nl2br\')\n+ self.browser.getControl(name="form.widgets.markdown_extensions").value,\n+ "markdown.extensions.fenced_code\\nmarkdown.extensions.nl2br",\n+ )\n \n self.browser.getControl(\n- name=\'form.widgets.markdown_extensions\'\n- ).value = \'\\n\'.join([\n- \'markdown.extensions.fenced_code\',\n- \'markdown.extensions.nl2br\',\n- \'markdown.extensions.extra\',\n- ])\n- self.browser.getControl(\'Save\').click()\n+ name="form.widgets.markdown_extensions"\n+ ).value = "\\n".join(\n+ [\n+ "markdown.extensions.fenced_code",\n+ "markdown.extensions.nl2br",\n+ "markdown.extensions.extra",\n+ ]\n+ )\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n- settings = registry.forInterface(IMarkupSchema, prefix=\'plone\')\n+ settings = registry.forInterface(IMarkupSchema, prefix="plone")\n self.assertEqual(\n settings.markdown_extensions,\n [\n- \'markdown.extensions.fenced_code\',\n- \'markdown.extensions.nl2br\',\n- \'markdown.extensions.extra\',\n- ]\n+ "markdown.extensions.fenced_code",\n+ "markdown.extensions.nl2br",\n+ "markdown.extensions.extra",\n+ ],\n )\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_navigation.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_navigation.py\nindex 93f614c828..bfc28b52f4 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_navigation.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_navigation.py\n@@ -18,134 +18,128 @@ class NavigationControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_navigation_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Navigation\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Navigation").click()\n self.assertTrue("Navigation Settings" in self.browser.contents)\n \n def test_navigation_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@navigation-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@navigation-controlpanel" % self.portal_url)\n self.assertTrue("General" in self.browser.contents)\n \n def test_navigation_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@navigation-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@navigation-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_navigation_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="navigation-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="navigation-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_generate_tabs(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(INavigationSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@navigation-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(INavigationSchema, prefix="plone")\n+ self.browser.open("%s/@@navigation-controlpanel" % self.portal_url)\n self.assertEqual(settings.generate_tabs, True)\n self.assertEqual(\n- self.browser.getControl(\'Automatically generate tabs\').selected,\n- True\n+ self.browser.getControl("Automatically generate tabs").selected, True\n )\n- self.browser.getControl(\'Automatically generate tabs\').selected = False\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl("Automatically generate tabs").selected = False\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.generate_tabs, False)\n \n def test_nonfolderish_tabs(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(INavigationSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@navigation-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(INavigationSchema, prefix="plone")\n+ self.browser.open("%s/@@navigation-controlpanel" % self.portal_url)\n self.assertEqual(settings.generate_tabs, True)\n self.assertEqual(\n- self.browser.getControl(\'Automatically generate tabs\').selected,\n- True\n+ self.browser.getControl("Automatically generate tabs").selected, True\n )\n self.browser.getControl(\n- \'Generate tabs for items other than folders\').selected = False\n- self.browser.getControl(\'Save\').click()\n+ "Generate tabs for items other than folders"\n+ ).selected = False\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(settings.nonfolderish_tabs, False)\n \n def test_displayed_types(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(INavigationSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@navigation-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Collection\', index=0).selected = True\n- self.browser.getControl(\'Comment\').selected = True\n- self.browser.getControl(\'Event\').selected = True\n- self.browser.getControl(\'File\').selected = True\n- self.browser.getControl(\'Folder\').selected = True\n- self.browser.getControl(\'Image\').selected = True\n- self.browser.getControl(\'Link\').selected = True\n- self.browser.getControl(\'News Item\').selected = True\n- self.browser.getControl(\'Page\').selected = True\n- self.browser.getControl(\'Save\').click()\n-\n- self.assertTrue(\'Collection\' in settings.displayed_types)\n- self.assertTrue(\'Discussion Item\' in settings.displayed_types)\n- self.assertTrue(\'Event\' in settings.displayed_types)\n- self.assertTrue(\'File\' in settings.displayed_types)\n- self.assertTrue(\'Folder\' in settings.displayed_types)\n- self.assertTrue(\'Image\' in settings.displayed_types)\n- self.assertTrue(\'Link\' in settings.displayed_types)\n- self.assertTrue(\'News Item\' in settings.displayed_types)\n- self.assertTrue(\'Document\' in settings.displayed_types)\n+ settings = registry.forInterface(INavigationSchema, prefix="plone")\n+ self.browser.open("%s/@@navigation-controlpanel" % self.portal_url)\n+ self.browser.getControl("Collection", index=0).selected = True\n+ self.browser.getControl("Comment").selected = True\n+ self.browser.getControl("Event").selected = True\n+ self.browser.getControl("File").selected = True\n+ self.browser.getControl("Folder").selected = True\n+ self.browser.getControl("Image").selected = True\n+ self.browser.getControl("Link").selected = True\n+ self.browser.getControl("News Item").selected = True\n+ self.browser.getControl("Page").selected = True\n+ self.browser.getControl("Save").click()\n+\n+ self.assertTrue("Collection" in settings.displayed_types)\n+ self.assertTrue("Discussion Item" in settings.displayed_types)\n+ self.assertTrue("Event" in settings.displayed_types)\n+ self.assertTrue("File" in settings.displayed_types)\n+ self.assertTrue("Folder" in settings.displayed_types)\n+ self.assertTrue("Image" in settings.displayed_types)\n+ self.assertTrue("Link" in settings.displayed_types)\n+ self.assertTrue("News Item" in settings.displayed_types)\n+ self.assertTrue("Document" in settings.displayed_types)\n \n def test_workflow_settings(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(INavigationSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@navigation-controlpanel" % self.portal_url)\n-\n- self.browser.getControl(\'Filter on workflow state\').selected = True\n- self.browser.getControl(\'Externally visible [external]\').selected = True # noqa\n- self.browser.getControl(\'Internal draft [internal]\').selected = True\n- self.browser.getControl(\'Internally published [internally_published]\').selected = True # noqa\n- self.browser.getControl(\'Pending [pending]\').selected = True\n- self.browser.getControl(\'Private [private]\').selected = True\n- self.browser.getControl(\'Public draft [visible]\').selected = True\n- self.browser.getControl(\'Published [published]\').selected = True\n+ settings = registry.forInterface(INavigationSchema, prefix="plone")\n+ self.browser.open("%s/@@navigation-controlpanel" % self.portal_url)\n+\n+ self.browser.getControl("Filter on workflow state").selected = True\n+ self.browser.getControl("Externally visible [external]").selected = True # noqa\n+ self.browser.getControl("Internal draft [internal]").selected = True\n+ self.browser.getControl(\n+ "Internally published [internally_published]"\n+ ).selected = True # noqa\n+ self.browser.getControl("Pending [pending]").selected = True\n+ self.browser.getControl("Private [private]").selected = True\n+ self.browser.getControl("Public draft [visible]").selected = True\n+ self.browser.getControl("Published [published]").selected = True\n self.browser.getControl("Save").click()\n \n- self.assertTrue(self.browser.url.endswith(\'navigation-controlpanel\'))\n- self.assertTrue(\'Changes saved.\' in self.browser.contents)\n+ self.assertTrue(self.browser.url.endswith("navigation-controlpanel"))\n+ self.assertTrue("Changes saved." in self.browser.contents)\n \n self.assertTrue(settings.filter_on_workflow)\n \n- self.assertTrue(\'external\' in settings.workflow_states_to_show)\n- self.assertTrue(\'internal\' in settings.workflow_states_to_show)\n- self.assertTrue(\'internally_published\' in settings.workflow_states_to_show) # noqa\n- self.assertTrue(\'pending\' in settings.workflow_states_to_show)\n- self.assertTrue(\'private\' in settings.workflow_states_to_show)\n- self.assertTrue(\'visible\' in settings.workflow_states_to_show)\n- self.assertTrue(\'published\' in settings.workflow_states_to_show)\n+ self.assertTrue("external" in settings.workflow_states_to_show)\n+ self.assertTrue("internal" in settings.workflow_states_to_show)\n+ self.assertTrue(\n+ "internally_published" in settings.workflow_states_to_show\n+ ) # noqa\n+ self.assertTrue("pending" in settings.workflow_states_to_show)\n+ self.assertTrue("private" in settings.workflow_states_to_show)\n+ self.assertTrue("visible" in settings.workflow_states_to_show)\n+ self.assertTrue("published" in settings.workflow_states_to_show)\n \n def test_show_excluded_items(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(INavigationSchema, prefix=\'plone\')\n- self.browser.open(\n- "%s/@@navigation-controlpanel" % self.portal_url)\n+ settings = registry.forInterface(INavigationSchema, prefix="plone")\n+ self.browser.open("%s/@@navigation-controlpanel" % self.portal_url)\n \n self.browser.getControl(\n- \'Show items normally excluded from navigation if viewing their children.\').selected = False # noqa\n+ "Show items normally excluded from navigation if viewing their children."\n+ ).selected = False # noqa\n self.browser.getControl("Save").click()\n \n self.assertFalse(settings.show_excluded_items)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py\nindex ffc779744c..3a219f5e57 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py\n@@ -24,19 +24,19 @@ class RedirectionControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\',\n+ "Authorization",\n+ f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}",\n )\n \n def test_redirection_controlpanel_link(self):\n self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'URL Management\').click()\n+ self.browser.getLink("URL Management").click()\n \n def test_redirection_controlpanel_backlink(self):\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n@@ -44,10 +44,8 @@ def test_redirection_controlpanel_backlink(self):\n \n def test_redirection_controlpanel_sidebar(self):\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_redirection_controlpanel_view(self):\n view = getMultiAdapter(\n@@ -57,14 +55,14 @@ def test_redirection_controlpanel_view(self):\n \n def test_redirection_controlpanel_add_redirect(self):\n storage = getUtility(IRedirectionStorage)\n- redirection_path = \'/alias-folder\'\n- target_path = \'/test-folder\'\n- storage_path = \'/plone/alias-folder\'\n+ redirection_path = "/alias-folder"\n+ target_path = "/test-folder"\n+ storage_path = "/plone/alias-folder"\n \n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'redirection\').value = redirection_path\n- self.browser.getControl(name=\'target_path\').value = target_path\n- self.browser.getControl(name=\'form.button.Add\').click()\n+ self.browser.getControl(name="redirection").value = redirection_path\n+ self.browser.getControl(name="target_path").value = target_path\n+ self.browser.getControl(name="form.button.Add").click()\n \n self.assertTrue(\n storage.has_path(storage_path),\n@@ -74,73 +72,72 @@ def test_redirection_controlpanel_add_redirect(self):\n def test_redirection_controlpanel_remove_redirects(self):\n storage = getUtility(IRedirectionStorage)\n for i in range(31):\n- storage[f\'/plone/alias{i}\'] = \'/plone/test-folder\'\n+ storage[f"/plone/alias{i}"] = "/plone/test-folder"\n transaction.commit()\n \n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n # A batch of 15 is shown, so some are missing.\n- self.assertTrue(\'/plone/alias1\' in self.browser.contents)\n- self.assertTrue(\'/plone/alias10\' in self.browser.contents)\n- self.assertTrue(\'/plone/alias19\' in self.browser.contents)\n- self.assertTrue(\'/plone/alias2\' in self.browser.contents)\n- self.assertFalse(\'/plone/alias29\' in self.browser.contents)\n+ self.assertTrue("/plone/alias1" in self.browser.contents)\n+ self.assertTrue("/plone/alias10" in self.browser.contents)\n+ self.assertTrue("/plone/alias19" in self.browser.contents)\n+ self.assertTrue("/plone/alias2" in self.browser.contents)\n+ self.assertFalse("/plone/alias29" in self.browser.contents)\n # query aliases starting with /alias2\n- self.browser.getControl(name=\'q\').value = \'/alias2\'\n- self.browser.getControl(name=\'form.button.filter\').click()\n- self.assertFalse(\'/plone/alias1\' in self.browser.contents)\n- self.assertTrue(\'/plone/alias2\' in self.browser.contents)\n- self.assertTrue(\'/plone/alias29\' in self.browser.contents)\n+ self.browser.getControl(name="q").value = "/alias2"\n+ self.browser.getControl(name="form.button.filter").click()\n+ self.assertFalse("/plone/alias1" in self.browser.contents)\n+ self.assertTrue("/plone/alias2" in self.browser.contents)\n+ self.assertTrue("/plone/alias29" in self.browser.contents)\n # The filter could return one value too much.\n # This tests that we have excludemax=True in the RedirectionSet.\n- self.assertFalse(\'/plone/alias3\' in self.browser.contents)\n- self.assertFalse(\'/plone/alias30\' in self.browser.contents)\n+ self.assertFalse("/plone/alias3" in self.browser.contents)\n+ self.assertFalse("/plone/alias30" in self.browser.contents)\n # Remove two.\n- self.browser.getControl(name=\'redirects:tuple\').value = [\n- \'/plone/alias2\',\n- \'/plone/alias20\',\n+ self.browser.getControl(name="redirects:tuple").value = [\n+ "/plone/alias2",\n+ "/plone/alias20",\n ]\n- self.browser.getControl(name=\'form.button.Remove\').click()\n- self.assertFalse(\'/plone/alias2\' in storage)\n- self.assertFalse(\'/plone/alias20\' in storage)\n- self.assertTrue(\'/plone/alias1\' in storage)\n- self.assertTrue(\'/plone/alias29\' in storage)\n- self.assertEqual(storage.get(\'/plone/alias29\'), \'/plone/test-folder\')\n+ self.browser.getControl(name="form.button.Remove").click()\n+ self.assertFalse("/plone/alias2" in storage)\n+ self.assertFalse("/plone/alias20" in storage)\n+ self.assertTrue("/plone/alias1" in storage)\n+ self.assertTrue("/plone/alias29" in storage)\n+ self.assertEqual(storage.get("/plone/alias29"), "/plone/test-folder")\n \n def test_redirection_controlpanel_remove_matching_redirects(self):\n storage = getUtility(IRedirectionStorage)\n for i in range(30):\n- storage[f\'/plone/alias{i}\'] = \'/plone/test-folder\'\n+ storage[f"/plone/alias{i}"] = "/plone/test-folder"\n transaction.commit()\n \n # Removing matching redirects can only happen when a filter is selected.\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'form.button.MatchRemove\').click()\n+ self.browser.getControl(name="form.button.MatchRemove").click()\n self.assertTrue(\n- \'No alternative urls selected for removal.\'\n- in self.browser.contents\n+ "No alternative urls selected for removal." in self.browser.contents\n )\n self.assertEqual(len(storage), 30)\n # query aliases starting with /alias2\n- self.browser.getControl(name=\'q\').value = \'/alias2\'\n+ self.browser.getControl(name="q").value = "/alias2"\n # The filter is immediately taken into account,\n # without first explicitly clicking filter.\n # self.browser.getControl(name=\'form.button.filter\').click()\n- self.browser.getControl(name=\'form.button.MatchRemove\').click()\n+ self.browser.getControl(name="form.button.MatchRemove").click()\n self.assertEqual(len(storage), 19)\n- self.assertFalse(\'/plone/alias2\' in storage)\n- self.assertFalse(\'/plone/alias20\' in storage)\n- self.assertFalse(\'/plone/alias29\' in storage)\n- self.assertTrue(\'/plone/alias1\' in storage)\n- self.assertTrue(\'/plone/alias12\' in storage)\n+ self.assertFalse("/plone/alias2" in storage)\n+ self.assertFalse("/plone/alias20" in storage)\n+ self.assertFalse("/plone/alias29" in storage)\n+ self.assertTrue("/plone/alias1" in storage)\n+ self.assertTrue("/plone/alias12" in storage)\n \n def test_redirection_controlpanel_set(self):\n storage = getUtility(IRedirectionStorage)\n- portal_path = self.layer[\'portal\'].absolute_url_path()\n- now = DateTime(\'2022-02-03\')\n+ portal_path = self.layer["portal"].absolute_url_path()\n+ now = DateTime("2022-02-03")\n for i in range(1000):\n storage.add(\n- f\'{portal_path:s}/foo/{str(i):s}\',\n- f\'{portal_path:s}/bar/{str(i):s}\',\n+ f"{portal_path:s}/foo/{str(i):s}",\n+ f"{portal_path:s}/bar/{str(i):s}",\n now=now,\n )\n redirects = RedirectionSet()\n@@ -148,148 +145,147 @@ def test_redirection_controlpanel_set(self):\n self.assertDictEqual(\n redirects[0],\n {\n- \'datetime\': DateTime(\'2022-02-03\'),\n- \'manual\': False,\n- \'path\': \'/foo/0\',\n- \'redirect\': f\'{portal_path:s}/foo/0\',\n- \'redirect-to\': \'/bar/0\',\n+ "datetime": DateTime("2022-02-03"),\n+ "manual": False,\n+ "path": "/foo/0",\n+ "redirect": f"{portal_path:s}/foo/0",\n+ "redirect-to": "/bar/0",\n },\n )\n self.assertDictEqual(\n redirects[999],\n {\n- \'datetime\': DateTime(\'2022-02-03\'),\n- \'manual\': False,\n- \'path\': \'/foo/999\',\n- \'redirect\': f\'{portal_path:s}/foo/999\',\n- \'redirect-to\': \'/bar/999\',\n+ "datetime": DateTime("2022-02-03"),\n+ "manual": False,\n+ "path": "/foo/999",\n+ "redirect": f"{portal_path:s}/foo/999",\n+ "redirect-to": "/bar/999",\n },\n )\n self.assertEqual(len(list(iter(redirects))), 1000)\n self.assertDictEqual(\n list(iter(redirects))[0],\n {\n- \'datetime\': DateTime(\'2022-02-03\'),\n- \'manual\': False,\n- \'path\': \'/foo/0\',\n- \'redirect\': f\'{portal_path:s}/foo/0\',\n- \'redirect-to\': \'/bar/0\',\n+ "datetime": DateTime("2022-02-03"),\n+ "manual": False,\n+ "path": "/foo/0",\n+ "redirect": f"{portal_path:s}/foo/0",\n+ "redirect-to": "/bar/0",\n },\n )\n \n def test_redirection_controlpanel_batching(self):\n storage = getUtility(IRedirectionStorage)\n- portal_path = self.layer[\'portal\'].absolute_url_path()\n+ portal_path = self.layer["portal"].absolute_url_path()\n for i in range(1000):\n storage.add(\n- f\'{portal_path:s}/foo/{str(i):s}\',\n- f\'{portal_path:s}/bar/{str(i):s}\',\n+ f"{portal_path:s}/foo/{str(i):s}",\n+ f"{portal_path:s}/bar/{str(i):s}",\n )\n view = getMultiAdapter(\n- (self.layer[\'portal\'], self.layer[\'request\']),\n- name=\'redirection-controlpanel\',\n+ (self.layer["portal"], self.layer["request"]),\n+ name="redirection-controlpanel",\n )\n # Test that view/redirects returns batch\n self.assertIsInstance(view.redirects(), Batch)\n \n # Test that view/batching returns batching with anchor in urls\n batching = view.batching()\n- self.assertIn(\'?b_start:int=990#manage-existing-aliases\', batching)\n+ self.assertIn("?b_start:int=990#manage-existing-aliases", batching)\n \n def test_redirection_controlpanel_redirect_alias_exists(self):\n- path_alias = \'/alias\'\n- path_target = \'/test-folder\'\n- storage_alias = f\'/plone{path_alias}\'\n- storage_target = f\'/plone{path_target}\'\n+ path_alias = "/alias"\n+ path_target = "/test-folder"\n+ storage_alias = f"/plone{path_alias}"\n+ storage_target = f"/plone{path_target}"\n storage = getUtility(IRedirectionStorage)\n storage.add(storage_alias, storage_target)\n transaction.commit()\n \n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'redirection\').value = path_alias\n- self.browser.getControl(name=\'target_path\').value = path_target\n- self.browser.getControl(name=\'form.button.Add\').click()\n+ self.browser.getControl(name="redirection").value = path_alias\n+ self.browser.getControl(name="target_path").value = path_target\n+ self.browser.getControl(name="form.button.Add").click()\n \n self.assertTrue(\n storage.get(storage_alias) == storage_target,\n- f\'{storage_target} not target of alternative url!\',\n+ f"{storage_target} not target of alternative url!",\n )\n self.assertTrue(\n- \'The provided alternative url already exists!\'\n- in self.browser.contents,\n+ "The provided alternative url already exists!" in self.browser.contents,\n \'Message "alternative url already exists" not in page!\',\n )\n \n def test_redirection_controlpanel_filtering(self):\n storage = getUtility(IRedirectionStorage)\n- portal_path = self.layer[\'portal\'].absolute_url_path()\n+ portal_path = self.layer["portal"].absolute_url_path()\n for i in range(1000):\n storage.add(\n- f\'{portal_path:s}/foo1/{str(i):s}\',\n- f\'{portal_path:s}/bar/{str(i):s}\',\n+ f"{portal_path:s}/foo1/{str(i):s}",\n+ f"{portal_path:s}/bar/{str(i):s}",\n )\n for i in range(1000):\n storage.add(\n- f\'{portal_path:s}/foo2/{str(i):s}\',\n- f\'{portal_path:s}/bar/{str(i):s}\',\n+ f"{portal_path:s}/foo2/{str(i):s}",\n+ f"{portal_path:s}/bar/{str(i):s}",\n )\n \n redirects = RedirectionSet()\n self.assertEqual(len(redirects), 2000)\n- redirects = RedirectionSet(query=\'/foo\')\n+ redirects = RedirectionSet(query="/foo")\n self.assertEqual(len(redirects), 2000)\n- redirects = RedirectionSet(query=\'/foo1\')\n+ redirects = RedirectionSet(query="/foo1")\n self.assertEqual(len(redirects), 1000)\n- redirects = RedirectionSet(query=\'/foo2\')\n+ redirects = RedirectionSet(query="/foo2")\n self.assertEqual(len(redirects), 1000)\n # this should return one and not two (we need excludemax=True)\n- redirects = RedirectionSet(query=\'/foo1/777\')\n+ redirects = RedirectionSet(query="/foo1/777")\n self.assertEqual(len(redirects), 1)\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'q\'] = \'/foo\'\n+ request = self.layer["request"].clone()\n+ request.form["q"] = "/foo"\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.0))\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'q\'] = \'/foo1\'\n+ request = self.layer["request"].clone()\n+ request.form["q"] = "/foo1"\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(1000 / 15.0))\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'q\'] = \'/foo2\'\n+ request = self.layer["request"].clone()\n+ request.form["q"] = "/foo2"\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(1000 / 15.0))\n \n- request = self.layer[\'request\'].clone()\n+ request = self.layer["request"].clone()\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.0))\n \n # Filtering without new request does not have effect because memoize\n- request.form[\'q\'] = \'/foo2\'\n+ request.form["q"] = "/foo2"\n self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.0))\n \n def test_redirection_controlpanel_filter_manual(self):\n storage = getUtility(IRedirectionStorage)\n- portal_path = self.layer[\'portal\'].absolute_url_path()\n+ portal_path = self.layer["portal"].absolute_url_path()\n for i in range(100):\n storage.add(\n- f\'{portal_path:s}/foo/{str(i):s}\',\n- f\'{portal_path:s}/bar/{str(i):s}\',\n+ f"{portal_path:s}/foo/{str(i):s}",\n+ f"{portal_path:s}/bar/{str(i):s}",\n manual=False,\n )\n for i in range(100, 300):\n storage.add(\n- f\'{portal_path:s}/foo/{str(i):s}\',\n- f\'{portal_path:s}/bar/{str(i):s}\',\n+ f"{portal_path:s}/foo/{str(i):s}",\n+ f"{portal_path:s}/bar/{str(i):s}",\n manual=True,\n )\n \n@@ -297,44 +293,44 @@ def test_redirection_controlpanel_filter_manual(self):\n self.assertEqual(len(redirects), 300)\n # Form has yes, no, or empty string, anything else is ignored\n # (so treated as empty string).\n- redirects = RedirectionSet(manual=\'yes\')\n+ redirects = RedirectionSet(manual="yes")\n self.assertEqual(len(redirects), 200)\n- redirects = RedirectionSet(manual=\'no\')\n+ redirects = RedirectionSet(manual="no")\n self.assertEqual(len(redirects), 100)\n- redirects = RedirectionSet(manual=\'\')\n+ redirects = RedirectionSet(manual="")\n self.assertEqual(len(redirects), 300)\n- redirects = RedirectionSet(manual=\'badvalue\')\n+ redirects = RedirectionSet(manual="badvalue")\n self.assertEqual(len(redirects), 300)\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'manual\'] = \'\'\n+ request = self.layer["request"].clone()\n+ request.form["manual"] = ""\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(300 / 15.0))\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'manual\'] = \'yes\'\n+ request = self.layer["request"].clone()\n+ request.form["manual"] = "yes"\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(200 / 15.0))\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'manual\'] = \'no\'\n+ request = self.layer["request"].clone()\n+ request.form["manual"] = "no"\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(100 / 15.0))\n \n def test_redirection_controlpanel_filter_date(self):\n storage = getUtility(IRedirectionStorage)\n- portal_path = self.layer[\'portal\'].absolute_url_path()\n- time0 = DateTime(\'2001-01-01\')\n+ portal_path = self.layer["portal"].absolute_url_path()\n+ time0 = DateTime("2001-01-01")\n for i in range(400):\n storage.add(\n- f\'{portal_path:s}/foo/{str(i):s}\',\n- f\'{portal_path:s}/bar/{str(i):s}\',\n+ f"{portal_path:s}/foo/{str(i):s}",\n+ f"{portal_path:s}/bar/{str(i):s}",\n now=time0 + i,\n )\n \n@@ -342,170 +338,162 @@ def test_redirection_controlpanel_filter_date(self):\n self.assertEqual(len(redirects), 400)\n # created can be anything that can be parsed by DateTime.\n # Otherwise it is ignored.\n- self.assertEqual(len(RedirectionSet(created=\'2019-01-01\')), 400)\n- self.assertEqual(len(RedirectionSet(created=\'1999-01-01\')), 0)\n- self.assertEqual(len(RedirectionSet(created=\'2001-01-01\')), 0)\n- self.assertEqual(len(RedirectionSet(created=\'2001-01-02\')), 1)\n- self.assertEqual(len(RedirectionSet(created=\'2001-02-01\')), 31)\n- self.assertEqual(len(RedirectionSet(created=\'2001-02-01 00:00:00\')), 31)\n- self.assertEqual(len(RedirectionSet(created=\'2001-02-01 00:00:01\')), 32)\n- self.assertEqual(len(RedirectionSet(created=\'badvalue\')), 400)\n+ self.assertEqual(len(RedirectionSet(created="2019-01-01")), 400)\n+ self.assertEqual(len(RedirectionSet(created="1999-01-01")), 0)\n+ self.assertEqual(len(RedirectionSet(created="2001-01-01")), 0)\n+ self.assertEqual(len(RedirectionSet(created="2001-01-02")), 1)\n+ self.assertEqual(len(RedirectionSet(created="2001-02-01")), 31)\n+ self.assertEqual(len(RedirectionSet(created="2001-02-01 00:00:00")), 31)\n+ self.assertEqual(len(RedirectionSet(created="2001-02-01 00:00:01")), 32)\n+ self.assertEqual(len(RedirectionSet(created="badvalue")), 400)\n \n # DateTime(\'2002-01-01\') results in a timezone GMT+0\n- self.assertEqual(len(RedirectionSet(created=\'2002-01-01\')), 365)\n+ self.assertEqual(len(RedirectionSet(created="2002-01-01")), 365)\n # DateTime(\'2002/01/01\') results in a timezone GMT+1 for me,\n # or a different zone depending on where in the world you are.\n # So we need to be lenient in the tests.\n- self.assertGreaterEqual(len(RedirectionSet(created=\'2002/01/01\')), 364)\n- self.assertLessEqual(len(RedirectionSet(created=\'2002/01/01\')), 366)\n+ self.assertGreaterEqual(len(RedirectionSet(created="2002/01/01")), 364)\n+ self.assertLessEqual(len(RedirectionSet(created="2002/01/01")), 366)\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'datetime\'] = \'\'\n+ request = self.layer["request"].clone()\n+ request.form["datetime"] = ""\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(400 / 15.0))\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'datetime\'] = \'2001-01-27\'\n+ request = self.layer["request"].clone()\n+ request.form["datetime"] = "2001-01-27"\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(27 / 15.0))\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'datetime\'] = \'2002-01-01\'\n+ request = self.layer["request"].clone()\n+ request.form["datetime"] = "2002-01-01"\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(365 / 15.0))\n \n- request = self.layer[\'request\'].clone()\n- request.form[\'datetime\'] = \'2019-01-01\'\n+ request = self.layer["request"].clone()\n+ request.form["datetime"] = "2019-01-01"\n view = getMultiAdapter(\n- (self.layer[\'portal\'], request), name=\'redirection-controlpanel\'\n+ (self.layer["portal"], request), name="redirection-controlpanel"\n )\n self.assertEqual(view.redirects().numpages, math.ceil(400 / 15.0))\n \n def test_redirection_controlpanel_redirect_no_target(self):\n- path_alias = \'/alias\'\n- path_target = \'/not-existing\'\n+ path_alias = "/alias"\n+ path_target = "/not-existing"\n \n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'redirection\').value = path_alias\n- self.browser.getControl(name=\'target_path\').value = path_target\n- self.browser.getControl(name=\'form.button.Add\').click()\n+ self.browser.getControl(name="redirection").value = path_alias\n+ self.browser.getControl(name="target_path").value = path_target\n+ self.browser.getControl(name="form.button.Add").click()\n \n self.assertTrue(\n- \'The provided target object does not exist.\'\n- in self.browser.contents,\n+ "The provided target object does not exist." in self.browser.contents,\n \'Message "target does not exist" not in page!\',\n )\n \n def test_redirection_controlpanel_missing_slash_target(self):\n- path_alias = \'/alias\'\n- path_target = \'Members\'\n+ path_alias = "/alias"\n+ path_target = "Members"\n \n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'redirection\').value = path_alias\n- self.browser.getControl(name=\'target_path\').value = path_target\n- self.browser.getControl(name=\'form.button.Add\').click()\n+ self.browser.getControl(name="redirection").value = path_alias\n+ self.browser.getControl(name="target_path").value = path_target\n+ self.browser.getControl(name="form.button.Add").click()\n \n self.assertTrue(\n- \'Target path must start with a slash.\' in self.browser.contents,\n- \'Errormessage for missing slash on target path missing\',\n+ "Target path must start with a slash." in self.browser.contents,\n+ "Errormessage for missing slash on target path missing",\n )\n \n def test_redirection_controlpanel_missing_slash_alias(self):\n- path_alias = \'alias\'\n- path_target = \'/Members\'\n+ path_alias = "alias"\n+ path_target = "/Members"\n \n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'redirection\').value = path_alias\n- self.browser.getControl(name=\'target_path\').value = path_target\n- self.browser.getControl(name=\'form.button.Add\').click()\n+ self.browser.getControl(name="redirection").value = path_alias\n+ self.browser.getControl(name="target_path").value = path_target\n+ self.browser.getControl(name="form.button.Add").click()\n \n self.assertTrue(\n- \'Alternative url path must start with a slash.\'\n- in self.browser.contents,\n- \'Errormessage for missing slash on alternative url missing\',\n+ "Alternative url path must start with a slash." in self.browser.contents,\n+ "Errormessage for missing slash on alternative url missing",\n )\n \n def test_manage_aliases_standard(self):\n storage = getUtility(IRedirectionStorage)\n- folder = self.portal[\'test-folder\']\n+ folder = self.portal["test-folder"]\n \n self.browser.open("%s/@@manage-aliases" % folder.absolute_url())\n- self.browser.getControl(name=\'redirection\').value = \'/alias\'\n- self.browser.getControl(name=\'form.button.Add\').click()\n+ self.browser.getControl(name="redirection").value = "/alias"\n+ self.browser.getControl(name="form.button.Add").click()\n \n self.assertTrue(\n- \'Alternative url added.\' in self.browser.contents,\n- \'Message for added alternative url missing\',\n+ "Alternative url added." in self.browser.contents,\n+ "Message for added alternative url missing",\n )\n- self.assertTrue(storage.has_path(\'/plone/alias\'))\n- self.assertEqual(storage.get(\'/plone/alias\'), \'/plone/test-folder\')\n+ self.assertTrue(storage.has_path("/plone/alias"))\n+ self.assertEqual(storage.get("/plone/alias"), "/plone/test-folder")\n \n def test_manage_aliases_remove(self):\n storage = getUtility(IRedirectionStorage)\n- folder = self.portal[\'test-folder\']\n- storage[\'/plone/alias1\'] = \'/plone/test-folder\'\n- storage[\'/plone/alias2\'] = \'/plone/test-folder\'\n- storage[\'/plone/alias3\'] = \'/plone/test-folder\'\n+ folder = self.portal["test-folder"]\n+ storage["/plone/alias1"] = "/plone/test-folder"\n+ storage["/plone/alias2"] = "/plone/test-folder"\n+ storage["/plone/alias3"] = "/plone/test-folder"\n transaction.commit()\n \n self.browser.open("%s/@@manage-aliases" % folder.absolute_url())\n- self.browser.getControl(name=\'redirects:tuple\').value = [\n- \'/plone/alias1\',\n- \'/plone/alias2\',\n+ self.browser.getControl(name="redirects:tuple").value = [\n+ "/plone/alias1",\n+ "/plone/alias2",\n ]\n- self.browser.getControl(name=\'form.button.Remove\').click()\n+ self.browser.getControl(name="form.button.Remove").click()\n \n self.assertTrue(\n- \'Alternative urls removed.\' in self.browser.contents,\n- \'Message for removed alternative url missing\',\n+ "Alternative urls removed." in self.browser.contents,\n+ "Message for removed alternative url missing",\n )\n- self.assertFalse(\'/plone/alias1\' in storage)\n- self.assertFalse(\'/plone/alias2\' in storage)\n- self.assertTrue(\'/plone/alias3\' in storage)\n- self.assertEqual(storage.get(\'/plone/alias3\'), \'/plone/test-folder\')\n+ self.assertFalse("/plone/alias1" in storage)\n+ self.assertFalse("/plone/alias2" in storage)\n+ self.assertTrue("/plone/alias3" in storage)\n+ self.assertEqual(storage.get("/plone/alias3"), "/plone/test-folder")\n \n def test_manage_aliases_navigation_root(self):\n from plone.app.layout.navigation.interfaces import INavigationRoot\n from zope.interface import alsoProvides\n \n storage = getUtility(IRedirectionStorage)\n- folder = self.portal[\'test-folder\']\n+ folder = self.portal["test-folder"]\n alsoProvides(folder, INavigationRoot)\n transaction.commit()\n \n self.browser.open("%s/@@manage-aliases" % folder.absolute_url())\n- self.browser.getControl(name=\'redirection\').value = \'/alias\'\n- self.browser.getControl(name=\'form.button.Add\').click()\n+ self.browser.getControl(name="redirection").value = "/alias"\n+ self.browser.getControl(name="form.button.Add").click()\n \n self.assertTrue(\n- \'Alternative url added.\' in self.browser.contents,\n- \'Message for added alternative url missing\',\n- )\n- self.assertTrue(storage.has_path(\'/plone/test-folder/alias\'))\n- self.assertEqual(\n- storage.get(\'/plone/test-folder/alias\'), \'/plone/test-folder\'\n+ "Alternative url added." in self.browser.contents,\n+ "Message for added alternative url missing",\n )\n+ self.assertTrue(storage.has_path("/plone/test-folder/alias"))\n+ self.assertEqual(storage.get("/plone/test-folder/alias"), "/plone/test-folder")\n \n # Add the navigation root path explicitly.\n- self.browser.getControl(\n- name=\'redirection\'\n- ).value = \'/test-folder/alias2\'\n- self.browser.getControl(name=\'form.button.Add\').click()\n+ self.browser.getControl(name="redirection").value = "/test-folder/alias2"\n+ self.browser.getControl(name="form.button.Add").click()\n \n self.assertTrue(\n- \'Alternative url added.\' in self.browser.contents,\n- \'Message for added alternative url missing\',\n- )\n- self.assertTrue(storage.has_path(\'/plone/test-folder/alias2\'))\n- self.assertEqual(\n- storage.get(\'/plone/test-folder/alias2\'), \'/plone/test-folder\'\n+ "Alternative url added." in self.browser.contents,\n+ "Message for added alternative url missing",\n )\n+ self.assertTrue(storage.has_path("/plone/test-folder/alias2"))\n+ self.assertEqual(storage.get("/plone/test-folder/alias2"), "/plone/test-folder")\n \n def test_absolutize_path(self):\n # absolutize_path is a helper function that returns a tuple\n@@ -515,59 +503,57 @@ def test_absolutize_path(self):\n )\n \n # A path is required.\n- self.assertEqual(ap(\'\'), (\'\', \'You have to enter an alternative url.\'))\n- self.assertEqual(\n- ap(\'\', is_source=False), (\'\', \'You have to enter a target.\')\n- )\n+ self.assertEqual(ap(""), ("", "You have to enter an alternative url."))\n+ self.assertEqual(ap("", is_source=False), ("", "You have to enter a target."))\n \n # relative paths are not accepted\n self.assertEqual(\n- ap(\'foo\'), (\'foo\', \'Alternative url path must start with a slash.\')\n+ ap("foo"), ("foo", "Alternative url path must start with a slash.")\n )\n self.assertEqual(\n- ap(\'foo\', is_source=True),\n- (\'foo\', \'Alternative url path must start with a slash.\'),\n+ ap("foo", is_source=True),\n+ ("foo", "Alternative url path must start with a slash."),\n )\n self.assertEqual(\n- ap(\'foo\', is_source=False),\n- (\'foo\', \'Target path must start with a slash.\'),\n+ ap("foo", is_source=False),\n+ ("foo", "Target path must start with a slash."),\n )\n \n # absolute paths are good\n- self.assertEqual(ap(\'/foo\'), (\'/plone/foo\', None))\n- self.assertEqual(ap(\'/foo\', is_source=True), (\'/plone/foo\', None))\n+ self.assertEqual(ap("/foo"), ("/plone/foo", None))\n+ self.assertEqual(ap("/foo", is_source=True), ("/plone/foo", None))\n \n # for targets, an object must exist on the path\n self.assertEqual(\n- ap(\'/foo\', is_source=False),\n- (\'/plone/foo\', \'The provided target object does not exist.\'),\n+ ap("/foo", is_source=False),\n+ ("/plone/foo", "The provided target object does not exist."),\n )\n self.assertEqual(\n- ap(\'/test-folder\', is_source=False), (\'/plone/test-folder\', None)\n+ ap("/test-folder", is_source=False), ("/plone/test-folder", None)\n )\n self.assertEqual(\n- ap(\'/test-folder/@@sharing\', is_source=False),\n- (\'/test-folder/@@sharing\', \'Target path must not be a view.\'),\n+ ap("/test-folder/@@sharing", is_source=False),\n+ ("/test-folder/@@sharing", "Target path must not be a view."),\n )\n \n # A source must not exist.\n self.assertEqual(\n- ap(\'/test-folder\'),\n+ ap("/test-folder"),\n (\n- \'/plone/test-folder\',\n- \'Cannot use a working path as alternative url.\',\n+ "/plone/test-folder",\n+ "Cannot use a working path as alternative url.",\n ),\n )\n # More general: a source must not be traversable already.\n self.assertEqual(\n- ap(\'/view\'),\n- (\'/plone/view\', \'Cannot use a working path as alternative url.\'),\n+ ap("/view"),\n+ ("/plone/view", "Cannot use a working path as alternative url."),\n )\n self.assertEqual(\n- ap(\'/@@overview-controlpanel\'),\n+ ap("/@@overview-controlpanel"),\n (\n- \'/@@overview-controlpanel\',\n- \'Alternative url path must not be a view.\',\n+ "/@@overview-controlpanel",\n+ "Alternative url path must not be a view.",\n ),\n )\n \n@@ -575,12 +561,12 @@ def test_absolutize_path(self):\n # We might *want* to allow this, but such a redirect would not have effect,\n # because acquisition happens earlier.\n # See https://github.com/collective/Products.RedirectionTool/issues/12\n- self.portal.invokeFactory(\'Document\', \'doc\')\n+ self.portal.invokeFactory("Document", "doc")\n self.assertEqual(\n- ap(\'/test-folder/doc\'),\n+ ap("/test-folder/doc"),\n (\n- \'/plone/test-folder/doc\',\n- \'Cannot use a working path as alternative url.\',\n+ "/plone/test-folder/doc",\n+ "Cannot use a working path as alternative url.",\n ),\n )\n \n@@ -588,43 +574,43 @@ def test_absolutize_path(self):\n storage = getUtility(IRedirectionStorage)\n portal_path = self.portal.absolute_url_path()\n storage.add(\n- f\'{portal_path:s}/foo\',\n- f\'{portal_path:s}/test-folder\',\n+ f"{portal_path:s}/foo",\n+ f"{portal_path:s}/test-folder",\n )\n self.assertEqual(\n- ap(\'/foo\', is_source=True),\n- (\'/plone/foo\', \'The provided alternative url already exists!\'),\n+ ap("/foo", is_source=True),\n+ ("/plone/foo", "The provided alternative url already exists!"),\n )\n \n # For targets, we now accept external urls.\n # Note that this can only be done on the control panel,\n # so by default only by Site Administrators or Managers.\n self.assertEqual(\n- ap(\'https://example.org\', is_source=False),\n- (\'https://example.org\', None),\n+ ap("https://example.org", is_source=False),\n+ ("https://example.org", None),\n )\n self.assertEqual(\n- ap(\'http://example.org\', is_source=False),\n- (\'http://example.org\', None),\n+ ap("http://example.org", is_source=False),\n+ ("http://example.org", None),\n )\n self.assertEqual(\n ap(\n- \'https://example.org/some/path?foo=bar&bar=foo\',\n+ "https://example.org/some/path?foo=bar&bar=foo",\n is_source=False,\n ),\n- (\'https://example.org/some/path?foo=bar&bar=foo\', None),\n+ ("https://example.org/some/path?foo=bar&bar=foo", None),\n )\n self.assertEqual(\n- ap(\'http://\', is_source=False),\n- (\'http://\', \'Target path must start with a slash.\'),\n+ ap("http://", is_source=False),\n+ ("http://", "Target path must start with a slash."),\n )\n # Using \'//\' to ignore http/https differences seems useless,\n # as we don\'t include content but only link to it.\n self.assertEqual(\n- ap(\'//example.org\', is_source=False),\n+ ap("//example.org", is_source=False),\n (\n- \'/plone//example.org\',\n- \'The provided target object does not exist.\',\n+ "/plone//example.org",\n+ "The provided target object does not exist.",\n ),\n )\n \n@@ -632,30 +618,24 @@ def test_upload_two_columns(self):\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n # Note: the targets must exist as actual content.\n data = [\n- (b\'/old-home-page.asp\', b\'/test-folder\'),\n- (b\'/people/JoeT\', b\'/Members\'),\n+ (b"/old-home-page.asp", b"/test-folder"),\n+ (b"/people/JoeT", b"/Members"),\n ]\n- csv = b\'\\n\'.join([b\',\'.join(d) for d in data])\n- self.browser.getControl(name=\'file\').add_file(\n- io.BytesIO(csv), \'text/plain\', \'redirects.csv\'\n- )\n- self.browser.getControl(name=\'form.button.Upload\').click()\n- self.assertNotIn(\n- \'Please pick a file to upload.\', self.browser.contents\n- )\n- self.assertNotIn(\n- \'No alternative urls were added.\', self.browser.contents\n- )\n- self.assertNotIn(\'Please correct these errors\', self.browser.contents)\n+ csv = b"\\n".join([b",".join(d) for d in data])\n+ self.browser.getControl(name="file").add_file(\n+ io.BytesIO(csv), "text/plain", "redirects.csv"\n+ )\n+ self.browser.getControl(name="form.button.Upload").click()\n+ self.assertNotIn("Please pick a file to upload.", self.browser.contents)\n+ self.assertNotIn("No alternative urls were added.", self.browser.contents)\n+ self.assertNotIn("Please correct these errors", self.browser.contents)\n storage = getUtility(IRedirectionStorage)\n self.assertEqual(len(storage), 2)\n- self.assertEqual(\n- storage.get(\'/plone/old-home-page.asp\'), \'/plone/test-folder\'\n- )\n- self.assertEqual(storage.get(\'/plone/people/JoeT\'), \'/plone/Members\')\n+ self.assertEqual(storage.get("/plone/old-home-page.asp"), "/plone/test-folder")\n+ self.assertEqual(storage.get("/plone/people/JoeT"), "/plone/Members")\n # Test the internals.\n- redirect = storage._paths[\'/plone/old-home-page.asp\']\n- self.assertEqual(redirect[0], \'/plone/test-folder\')\n+ redirect = storage._paths["/plone/old-home-page.asp"]\n+ self.assertEqual(redirect[0], "/plone/test-folder")\n self.assertIsInstance(redirect[1], DateTime)\n self.assertEqual(redirect[2], True) # manual\n \n@@ -671,96 +651,92 @@ def test_upload_four_columns(self):\n # We can first have a header, which should be ignored.\n # Second one should have the same number of columns,\n # otherwise the delimiter detection can get it wrong.\n- (b\'old path\', b\'new path\', b\'datetime\', b\'manual\'),\n+ (b"old path", b"new path", b"datetime", b"manual"),\n # bad dates are silently ignored\n- (b\'/baddate\', b\'/test-folder\', b\'2006-13-62\', b\'yes\'),\n+ (b"/baddate", b"/test-folder", b"2006-13-62", b"yes"),\n # two columns:\n- (b\'/two\', b\'/test-folder\'),\n+ (b"/two", b"/test-folder"),\n # third column with date:\n- (b\'/three\', b\'/test-folder\', b\'2003-01-31\'),\n+ (b"/three", b"/test-folder", b"2003-01-31"),\n # fourth column with manual:\n (\n- b\'/four\',\n- b\'/test-folder\',\n- b\'2004/01/27 10:00:00 GMT-3\',\n- b\'False\',\n+ b"/four",\n+ b"/test-folder",\n+ b"2004/01/27 10:00:00 GMT-3",\n+ b"False",\n ),\n # fifth column is ignored:\n- (b\'/five\', b\'/test-folder\', b\'2005-01-31\', b\'True\', b\'ignored\'),\n+ (b"/five", b"/test-folder", b"2005-01-31", b"True", b"ignored"),\n # manual can be \'0\' (or anything starting with f/F/n/N/0)\n- (b\'/zero\', b\'/test-folder\', b\'2000-01-31\', b\'0\'),\n+ (b"/zero", b"/test-folder", b"2000-01-31", b"0"),\n ]\n- csv = b\'\\n\'.join([b\',\'.join(d) for d in data])\n- self.browser.getControl(name=\'file\').add_file(\n- io.BytesIO(csv), \'text/plain\', \'redirects.csv\'\n- )\n- self.browser.getControl(name=\'form.button.Upload\').click()\n- self.assertNotIn(\n- \'Please pick a file to upload.\', self.browser.contents\n+ csv = b"\\n".join([b",".join(d) for d in data])\n+ self.browser.getControl(name="file").add_file(\n+ io.BytesIO(csv), "text/plain", "redirects.csv"\n )\n- self.assertNotIn(\n- \'No alternative urls were added.\', self.browser.contents\n- )\n- self.assertNotIn(\'Please correct these errors\', self.browser.contents)\n+ self.browser.getControl(name="form.button.Upload").click()\n+ self.assertNotIn("Please pick a file to upload.", self.browser.contents)\n+ self.assertNotIn("No alternative urls were added.", self.browser.contents)\n+ self.assertNotIn("Please correct these errors", self.browser.contents)\n \n # All five lines have been added.\n storage = getUtility(IRedirectionStorage)\n self.assertEqual(len(storage), 6)\n- self.assertEqual(storage.get(\'/plone/two\'), \'/plone/test-folder\')\n+ self.assertEqual(storage.get("/plone/two"), "/plone/test-folder")\n old_paths = [\n- \'/plone/baddate\',\n- \'/plone/five\',\n- \'/plone/four\',\n- \'/plone/three\',\n- \'/plone/two\',\n- \'/plone/zero\',\n+ "/plone/baddate",\n+ "/plone/five",\n+ "/plone/four",\n+ "/plone/three",\n+ "/plone/two",\n+ "/plone/zero",\n ]\n self.assertListEqual(sorted(list(storage)), old_paths)\n self.assertListEqual(\n- sorted(list(storage.redirects(\'/plone/test-folder\'))), old_paths\n+ sorted(list(storage.redirects("/plone/test-folder"))), old_paths\n )\n # Test the internals.\n \n # two columns:\n # (b\'/two\', b\'/test-folder\'),\n- redirect = storage._paths[\'/plone/two\']\n- self.assertEqual(redirect[0], \'/plone/test-folder\')\n+ redirect = storage._paths["/plone/two"]\n+ self.assertEqual(redirect[0], "/plone/test-folder")\n self.assertIsInstance(redirect[1], DateTime)\n self.assertGreater(redirect[1], now)\n self.assertEqual(redirect[2], True) # manual\n \n # third column with date:\n # (b\'/three\', b\'/test-folder\', b\'2003-01-31\'),\n- redirect = storage._paths[\'/plone/three\']\n- self.assertEqual(redirect[0], \'/plone/test-folder\')\n- self.assertEqual(redirect[1], DateTime(\'2003-01-31\'))\n+ redirect = storage._paths["/plone/three"]\n+ self.assertEqual(redirect[0], "/plone/test-folder")\n+ self.assertEqual(redirect[1], DateTime("2003-01-31"))\n self.assertEqual(redirect[2], True)\n \n # fourth column with manual:\n # (b\'/four\', b\'/test-folder\', b\'2004/01/27 10:00:00 GMT-3\', b\'False\'),\n- redirect = storage._paths[\'/plone/four\']\n- self.assertEqual(redirect[0], \'/plone/test-folder\')\n- self.assertEqual(redirect[1], DateTime(\'2004/01/27 10:00:00 GMT-3\'))\n+ redirect = storage._paths["/plone/four"]\n+ self.assertEqual(redirect[0], "/plone/test-folder")\n+ self.assertEqual(redirect[1], DateTime("2004/01/27 10:00:00 GMT-3"))\n self.assertEqual(redirect[2], False)\n \n # fifth column is ignored:\n # (b\'/five\', b\'/test-folder\', b\'2005-01-31\', b\'True\', b\'ignored\'),\n- redirect = storage._paths[\'/plone/five\']\n- self.assertEqual(redirect[0], \'/plone/test-folder\')\n- self.assertEqual(redirect[1], DateTime(\'2005-01-31\'))\n+ redirect = storage._paths["/plone/five"]\n+ self.assertEqual(redirect[0], "/plone/test-folder")\n+ self.assertEqual(redirect[1], DateTime("2005-01-31"))\n self.assertEqual(redirect[2], True)\n \n # manual can be \'0\' (or anything starting with f/F/n/N/0)\n # (b\'/zero\', b\'/test-folder\', b\'2000-01-31\', b\'0\'),\n- redirect = storage._paths[\'/plone/zero\']\n- self.assertEqual(redirect[0], \'/plone/test-folder\')\n- self.assertEqual(redirect[1], DateTime(\'2000-01-31\'))\n+ redirect = storage._paths["/plone/zero"]\n+ self.assertEqual(redirect[0], "/plone/test-folder")\n+ self.assertEqual(redirect[1], DateTime("2000-01-31"))\n self.assertEqual(redirect[2], False)\n \n # bad dates are silently ignored\n # (b\'/baddate\', b\'/test-folder\', b\'2006-13-62\', b\'yes\'),\n- redirect = storage._paths[\'/plone/baddate\']\n- self.assertEqual(redirect[0], \'/plone/test-folder\')\n+ redirect = storage._paths["/plone/baddate"]\n+ self.assertEqual(redirect[0], "/plone/test-folder")\n self.assertGreater(redirect[1], now)\n self.assertEqual(redirect[2], True)\n \n@@ -769,65 +745,61 @@ def test_upload_bad(self):\n # The targets must exist as actual content.\n # We try a good one and one that does not exist.\n data = [\n- (b\'/old-home-page.asp\', b\'/test-folder\'),\n- (b\'/people/JoeT\', b\'/no-such-content\'),\n+ (b"/old-home-page.asp", b"/test-folder"),\n+ (b"/people/JoeT", b"/no-such-content"),\n ]\n- csv = b\'\\n\'.join([b\',\'.join(d) for d in data])\n- self.browser.getControl(name=\'file\').add_file(\n- io.BytesIO(csv), \'text/plain\', \'redirects.csv\'\n- )\n- self.browser.getControl(name=\'form.button.Upload\').click()\n- self.assertNotIn(\n- \'Please pick a file to upload.\', self.browser.contents\n- )\n- self.assertIn(\'No alternative urls were added.\', self.browser.contents)\n- self.assertIn(\'Please correct these errors\', self.browser.contents)\n+ csv = b"\\n".join([b",".join(d) for d in data])\n+ self.browser.getControl(name="file").add_file(\n+ io.BytesIO(csv), "text/plain", "redirects.csv"\n+ )\n+ self.browser.getControl(name="form.button.Upload").click()\n+ self.assertNotIn("Please pick a file to upload.", self.browser.contents)\n+ self.assertIn("No alternative urls were added.", self.browser.contents)\n+ self.assertIn("Please correct these errors", self.browser.contents)\n storage = getUtility(IRedirectionStorage)\n self.assertEqual(len(storage), 0)\n \n def test_download_empty(self):\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'form.button.Download\').click()\n+ self.browser.getControl(name="form.button.Download").click()\n self.assertEqual(\n- self.browser.headers[\'Content-Disposition\'],\n- \'attachment; filename=redirects.csv\',\n+ self.browser.headers["Content-Disposition"],\n+ "attachment; filename=redirects.csv",\n )\n contents = self.browser.contents.splitlines()\n self.assertEqual(len(contents), 1)\n- self.assertEqual(contents[0], \'old path,new path,datetime,manual\')\n+ self.assertEqual(contents[0], "old path,new path,datetime,manual")\n \n def test_download_bigger(self):\n storage = getUtility(IRedirectionStorage)\n- portal_path = self.layer[\'portal\'].absolute_url_path()\n- now = DateTime(\'2019/01/27 10:00:00 GMT-3\')\n+ portal_path = self.layer["portal"].absolute_url_path()\n+ now = DateTime("2019/01/27 10:00:00 GMT-3")\n for i in range(2000):\n storage.add(\n- f\'{portal_path:s}/foo/{str(i):s}\',\n- f\'{portal_path:s}/bar/{str(i):s}\',\n+ f"{portal_path:s}/foo/{str(i):s}",\n+ f"{portal_path:s}/bar/{str(i):s}",\n now=now,\n manual=True,\n )\n transaction.commit()\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'form.button.Download\').click()\n+ self.browser.getControl(name="form.button.Download").click()\n self.assertEqual(\n- self.browser.headers[\'Content-Disposition\'],\n- \'attachment; filename=redirects.csv\',\n+ self.browser.headers["Content-Disposition"],\n+ "attachment; filename=redirects.csv",\n )\n contents = self.browser.contents.splitlines()\n # pop the header\n- self.assertEqual(contents.pop(0), \'old path,new path,datetime,manual\')\n+ self.assertEqual(contents.pop(0), "old path,new path,datetime,manual")\n self.assertEqual(len(contents), 2000)\n # The order is probably the alphabetical order of the old path,\n # but that is not important and may change,\n # so let\'s sort it in the tests for good measure.\n # Note that \'999\' sorts alphabetically after \'1999\'.\n contents.sort()\n+ self.assertEqual(contents[0], "/foo/0,/bar/0,2019/01/27 10:00:00 GMT-3,True")\n self.assertEqual(\n- contents[0], \'/foo/0,/bar/0,2019/01/27 10:00:00 GMT-3,True\'\n- )\n- self.assertEqual(\n- contents[1999], \'/foo/999,/bar/999,2019/01/27 10:00:00 GMT-3,True\'\n+ contents[1999], "/foo/999,/bar/999,2019/01/27 10:00:00 GMT-3,True"\n )\n \n def test_download_upload(self):\n@@ -835,12 +807,12 @@ def test_download_upload(self):\n \n # 1. Manually add some redirects.\n storage = getUtility(IRedirectionStorage)\n- portal_path = self.layer[\'portal\'].absolute_url_path()\n- now = DateTime(\'2019/01/27 10:00:00 GMT-3\')\n+ portal_path = self.layer["portal"].absolute_url_path()\n+ now = DateTime("2019/01/27 10:00:00 GMT-3")\n for i in range(10):\n storage.add(\n- f\'{portal_path:s}/foo/{str(i):s}\',\n- f\'{portal_path:s}/test-folder\',\n+ f"{portal_path:s}/foo/{str(i):s}",\n+ f"{portal_path:s}/test-folder",\n now=now,\n manual=True,\n )\n@@ -848,58 +820,54 @@ def test_download_upload(self):\n \n # 2. Download the redirects.\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'form.button.Download\').click()\n+ self.browser.getControl(name="form.button.Download").click()\n self.assertEqual(\n- self.browser.headers[\'Content-Disposition\'],\n- \'attachment; filename=redirects.csv\',\n+ self.browser.headers["Content-Disposition"],\n+ "attachment; filename=redirects.csv",\n )\n downloaded_contents = self.browser.contents\n contents = downloaded_contents.splitlines()\n- self.assertEqual(contents.pop(0), \'old path,new path,datetime,manual\')\n+ self.assertEqual(contents.pop(0), "old path,new path,datetime,manual")\n self.assertEqual(len(contents), 10)\n contents.sort()\n self.assertEqual(\n- contents[0], \'/foo/0,/test-folder,2019/01/27 10:00:00 GMT-3,True\'\n+ contents[0], "/foo/0,/test-folder,2019/01/27 10:00:00 GMT-3,True"\n )\n \n # 3. clear the redirect storage\n storage.clear()\n transaction.commit()\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'form.button.Download\').click()\n+ self.browser.getControl(name="form.button.Download").click()\n contents = self.browser.contents.splitlines()\n self.assertEqual(len(contents), 1)\n- self.assertEqual(contents[0], \'old path,new path,datetime,manual\')\n+ self.assertEqual(contents[0], "old path,new path,datetime,manual")\n \n # 4. upload the original download\n self.browser.open("%s/@@redirection-controlpanel" % self.portal_url)\n- self.browser.getControl(name=\'file\').add_file(\n+ self.browser.getControl(name="file").add_file(\n io.BytesIO(safe_bytes(downloaded_contents)),\n- \'text/plain\',\n- \'redirects.csv\',\n- )\n- self.browser.getControl(name=\'form.button.Upload\').click()\n- self.assertNotIn(\n- \'Please pick a file to upload.\', self.browser.contents\n- )\n- self.assertNotIn(\n- \'The provided target object does not exist.\', self.browser.contents\n+ "text/plain",\n+ "redirects.csv",\n )\n+ self.browser.getControl(name="form.button.Upload").click()\n+ self.assertNotIn("Please pick a file to upload.", self.browser.contents)\n self.assertNotIn(\n- \'No alternative urls were added.\', self.browser.contents\n+ "The provided target object does not exist.", self.browser.contents\n )\n- self.assertNotIn(\'Please correct these errors\', self.browser.contents)\n+ self.assertNotIn("No alternative urls were added.", self.browser.contents)\n+ self.assertNotIn("Please correct these errors", self.browser.contents)\n self.assertEqual(len(storage), 10)\n \n # 5. download the upload\n- self.browser.getControl(name=\'form.button.Download\').click()\n+ self.browser.getControl(name="form.button.Download").click()\n new_downloaded_contents = self.browser.contents\n contents = downloaded_contents.splitlines()\n- self.assertEqual(contents.pop(0), \'old path,new path,datetime,manual\')\n+ self.assertEqual(contents.pop(0), "old path,new path,datetime,manual")\n self.assertEqual(len(contents), 10)\n contents.sort()\n self.assertEqual(\n- contents[0], \'/foo/0,/test-folder,2019/01/27 10:00:00 GMT-3,True\'\n+ contents[0], "/foo/0,/test-folder,2019/01/27 10:00:00 GMT-3,True"\n )\n # and it is actually the same as the original download\n self.assertEqual(new_downloaded_contents, downloaded_contents)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_search.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_search.py\nindex ebcf1f3b02..f2cc9bf507 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_search.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_search.py\n@@ -18,58 +18,52 @@ class SearchControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_search_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Search\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Search").click()\n \n def test_search_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@search-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@search-controlpanel" % self.portal_url)\n self.assertTrue("General" in self.browser.contents)\n \n def test_search_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@search-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@search-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_search_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="search-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="search-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_enable_livesearch(self):\n- self.browser.open(\n- "%s/@@search-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Enable LiveSearch\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@search-controlpanel" % self.portal_url)\n+ self.browser.getControl("Enable LiveSearch").selected = True\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISearchSchema, prefix="plone")\n self.assertEqual(settings.enable_livesearch, True)\n \n def test_types_not_searched(self):\n- self.browser.open(\n- "%s/@@search-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.types_not_searched:list\'\n- ).value = [\'Discussion Item\', \'News Item\']\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@search-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.types_not_searched:list").value = [\n+ "Discussion Item",\n+ "News Item",\n+ ]\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISearchSchema, prefix="plone")\n- self.assertTrue(\'Discussion Item\' in settings.types_not_searched)\n- self.assertTrue(\'News Item\' in settings.types_not_searched)\n+ self.assertTrue("Discussion Item" in settings.types_not_searched)\n+ self.assertTrue("News Item" in settings.types_not_searched)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_security.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_security.py\nindex fb1f64ecf9..fef6b62e37 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_security.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_security.py\n@@ -17,86 +17,70 @@ class SecurityControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ISecuritySchema, prefix="plone")\n+ self.settings = registry.forInterface(ISecuritySchema, prefix="plone")\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_security_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Security\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Security").click()\n \n def test_security_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@security-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@security-controlpanel" % self.portal_url)\n self.assertTrue("Security" in self.browser.contents)\n \n def test_security_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@security-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@security-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_enable_self_reg(self):\n- self.browser.open(\n- "%s/@@security-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Enable self-registration\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@security-controlpanel" % self.portal_url)\n+ self.browser.getControl("Enable self-registration").selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.enable_self_reg, True)\n \n def test_enable_user_pwd_choice(self):\n- self.browser.open(\n- "%s/@@security-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- \'Let users select their own passwords\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@security-controlpanel" % self.portal_url)\n+ self.browser.getControl("Let users select their own passwords").selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.enable_user_pwd_choice, True)\n \n def test_enable_user_folders(self):\n- self.browser.open(\n- "%s/@@security-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- \'Enable User Folders\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@security-controlpanel" % self.portal_url)\n+ self.browser.getControl("Enable User Folders").selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.enable_user_folders, True)\n \n def test_allow_anon_views_about(self):\n- self.browser.open(\n- "%s/@@security-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@security-controlpanel" % self.portal_url)\n self.browser.getControl(\n- "Allow anyone to view \'about\' information").selected = True\n- self.browser.getControl(\'Save\').click()\n+ "Allow anyone to view \'about\' information"\n+ ).selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.allow_anon_views_about, True)\n \n def test_use_email_as_login(self):\n- self.browser.open(\n- "%s/@@security-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- "Use email address as login name").selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@security-controlpanel" % self.portal_url)\n+ self.browser.getControl("Use email address as login name").selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.use_email_as_login, True)\n \n def test_use_uuid_as_userid(self):\n- self.browser.open(\n- "%s/@@security-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- "Use UUID user ids").selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@security-controlpanel" % self.portal_url)\n+ self.browser.getControl("Use UUID user ids").selected = True\n+ self.browser.getControl("Save").click()\n \n self.assertEqual(self.settings.use_uuid_as_userid, True)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_site.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_site.py\nindex 3bf8436942..9d581b7d0a 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_site.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_site.py\n@@ -12,14 +12,18 @@\n \n \n # Red pixel with filename pixel.png\n-SITE_LOGO_BASE64 = b\'filenameb64:cGl4ZWwucG5n;datab64:iVBORw0KGgoAAAANSUhEUgA\'\\\n- b\'AAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAA\'\\\n- b\'AAElFTkSuQmCC\'\n+SITE_LOGO_BASE64 = (\n+ b"filenameb64:cGl4ZWwucG5n;datab64:iVBORw0KGgoAAAANSUhEUgA"\n+ b"AAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAA"\n+ b"AAElFTkSuQmCC"\n+)\n \n-SITE_LOGO_HEX = b\'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR\\x00\\x00\\x00\\x01\\x00\\x00\'\\\n- b\'\\x00\\x01\\x08\\x02\\x00\\x00\\x00\\x90wS\\xde\\x00\\x00\\x00\\x0cIDAT\'\\\n- b\'\\x08\\xd7c\\xf8\\xcf\\xc0\\x00\\x00\\x03\\x01\\x01\\x00\\x18\\xdd\\x8d\'\\\n- b\'\\xb0\\x00\\x00\\x00\\x00IEND\\xaeB`\\x82\'\n+SITE_LOGO_HEX = (\n+ b"\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR\\x00\\x00\\x00\\x01\\x00\\x00"\n+ b"\\x00\\x01\\x08\\x02\\x00\\x00\\x00\\x90wS\\xde\\x00\\x00\\x00\\x0cIDAT"\n+ b"\\x08\\xd7c\\xf8\\xcf\\xc0\\x00\\x00\\x03\\x01\\x01\\x00\\x18\\xdd\\x8d"\n+ b"\\xb0\\x00\\x00\\x00\\x00IEND\\xaeB`\\x82"\n+)\n \n \n class SiteControlPanelFunctionalTest(unittest.TestCase):\n@@ -30,153 +34,135 @@ class SiteControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_site_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site").click()\n \n def test_site_control_panel_backlink(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n self.assertTrue("General" in self.browser.contents)\n \n def test_site_control_panel_sidebar(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_site_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="site-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="site-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_site_title_is_stored_in_registry(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "My Site"\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "My Site"\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISiteSchema, prefix="plone")\n self.assertEqual(settings.site_title, "My Site")\n \n def test_site_title_can_be_looked_up_by_plone_portal_state(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "My Site"\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "My Site"\n+ self.browser.getControl("Save").click()\n \n portal_state = getMultiAdapter(\n- (self.portal, self.request),\n- name=\'plone_portal_state\'\n+ (self.portal, self.request), name="plone_portal_state"\n )\n- self.assertEqual(portal_state.portal_title(), \'My Site\')\n+ self.assertEqual(portal_state.portal_title(), "My Site")\n \n @unittest.skip("XXX: TODO! We have to patch CMFDefault for this.")\n def test_site_title_can_be_looked_up_by_portal_title(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "My Site"\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "My Site"\n+ self.browser.getControl("Save").click()\n \n- self.assertEqual(self.portal.title, \'My Site\')\n- self.assertEqual(self.portal.Title(), \'My Site\')\n+ self.assertEqual(self.portal.title, "My Site")\n+ self.assertEqual(self.portal.Title(), "My Site")\n \n def test_site_logo_is_stored_in_registry(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n ctrl = self.browser.getControl(name="form.widgets.site_logo")\n- ctrl.add_file(BytesIO(SITE_LOGO_HEX), \'image/png\', \'pixel.png\')\n- self.browser.getControl(\'Save\').click()\n+ ctrl.add_file(BytesIO(SITE_LOGO_HEX), "image/png", "pixel.png")\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ISiteSchema, prefix=\'plone\')\n+ settings = registry.forInterface(ISiteSchema, prefix="plone")\n self.assertEqual(settings.site_logo, SITE_LOGO_BASE64)\n \n def test_exposeDCMetaTags(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "Plone Site"\n- self.browser.getControl(\'Expose Dublin Core metadata\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "Plone Site"\n+ self.browser.getControl("Expose Dublin Core metadata").selected = True\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISiteSchema, prefix="plone")\n self.assertEqual(settings.exposeDCMetaTags, True)\n \n def test_exposeDCMetaTags_exposes_meta_tags(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "Plone Site"\n- self.browser.getControl(\'Expose Dublin Core metadata\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "Plone Site"\n+ self.browser.getControl("Expose Dublin Core metadata").selected = True\n+ self.browser.getControl("Save").click()\n \n self.browser.open(self.portal_url)\n \n- self.assertTrue(\'DC.type\' in self.browser.contents)\n+ self.assertTrue("DC.type" in self.browser.contents)\n \n def test_enable_sitemap(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "Plone Site"\n- self.browser.getControl(\'Expose sitemap.xml.gz\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "Plone Site"\n+ self.browser.getControl("Expose sitemap.xml.gz").selected = True\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISiteSchema, prefix="plone")\n self.assertEqual(settings.enable_sitemap, True)\n \n def test_enable_sitemap_enables_the_sitemap(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "Plone Site"\n- self.browser.getControl(\'Expose sitemap.xml.gz\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "Plone Site"\n+ self.browser.getControl("Expose sitemap.xml.gz").selected = True\n+ self.browser.getControl("Save").click()\n \n self.browser.open("%s/sitemap.xml.gz" % self.portal_url)\n \n+ self.assertEqual(self.browser.headers["status"].lower(), "200 ok")\n self.assertEqual(\n- self.browser.headers[\'status\'].lower(),\n- \'200 ok\'\n- )\n- self.assertEqual(\n- self.browser.headers[\'content-type\'],\n- \'application/octet-stream\'\n+ self.browser.headers["content-type"], "application/octet-stream"\n )\n \n def test_webstats_js(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "Plone Site"\n- self.browser.getControl(name=\'form.widgets.webstats_js\').value = \\\n- ""\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "Plone Site"\n+ self.browser.getControl(\n+ name="form.widgets.webstats_js"\n+ ).value = ""\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISiteSchema, prefix="plone")\n self.assertEqual(settings.webstats_js, "")\n \n def test_webstat_js_shows_up_on_site(self):\n- self.browser.open(\n- "%s/@@site-controlpanel" % self.portal_url)\n- self.browser.getControl(\'Site title\').value = "Plone Site"\n- self.browser.getControl(name=\'form.widgets.webstats_js\').value = \\\n- ""\n- self.browser.getControl(\'Save\').click()\n+ self.browser.open("%s/@@site-controlpanel" % self.portal_url)\n+ self.browser.getControl("Site title").value = "Plone Site"\n+ self.browser.getControl(\n+ name="form.widgets.webstats_js"\n+ ).value = ""\n+ self.browser.getControl("Save").click()\n \n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISiteSchema, prefix="plone")\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_syndication.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_syndication.py\nindex 60da102499..98f799eef2 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_syndication.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_syndication.py\n@@ -9,104 +9,90 @@\n \n \n class SyndicationControlPanelFunctionalTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_syndication_controlpanel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Syndication\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Syndication").click()\n \n def test_syndication_controlpanel_backlink(self):\n- self.browser.open(\n- "%s/@@syndication-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@syndication-controlpanel" % self.portal_url)\n self.assertTrue("General" in self.browser.contents)\n \n def test_syndication_controlpanel_sidebar(self):\n- self.browser.open(\n- "%s/@@syndication-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Site Setup\').click()\n- self.assertTrue(\n- self.browser.url.endswith(\'/plone/@@overview-controlpanel\')\n- )\n+ self.browser.open("%s/@@syndication-controlpanel" % self.portal_url)\n+ self.browser.getLink("Site Setup").click()\n+ self.assertTrue(self.browser.url.endswith("/plone/@@overview-controlpanel"))\n \n def test_syndication_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="syndication-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="syndication-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_syndication_controlpanel_enabled(self):\n- self.browser.open(\n- "%s/@@syndication-controlpanel" % self.portal_url)\n+ self.browser.open("%s/@@syndication-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.default_enabled:list").value = True\n+ self.browser.getControl(name="form.widgets.show_author_info:list").value = False\n self.browser.getControl(\n- name=\'form.widgets.default_enabled:list\').value = True\n- self.browser.getControl(\n- name=\'form.widgets.show_author_info:list\').value = False\n- self.browser.getControl(\n- name=\'form.widgets.show_syndication_link:list\').value = True\n- self.browser.getControl(\'Save\').click()\n+ name="form.widgets.show_syndication_link:list"\n+ ).value = True\n+ self.browser.getControl("Save").click()\n \n- self.assertTrue(\'Changes saved\' in self.browser.contents)\n- self.browser.open(\n- "%s/@@syndication-controlpanel" % self.portal_url)\n+ self.assertTrue("Changes saved" in self.browser.contents)\n+ self.browser.open("%s/@@syndication-controlpanel" % self.portal_url)\n \n self.assertEqual(\n- self.browser.getControl(\n- name=\'form.widgets.default_enabled:list\'\n- ).value,\n- [\'selected\']\n+ self.browser.getControl(name="form.widgets.default_enabled:list").value,\n+ ["selected"],\n )\n self.assertEqual(\n- self.browser.getControl(\n- name=\'form.widgets.show_author_info:list\').value,\n- []\n+ self.browser.getControl(name="form.widgets.show_author_info:list").value, []\n )\n self.assertEqual(\n self.browser.getControl(\n- name=\'form.widgets.show_syndication_link:list\'\n+ name="form.widgets.show_syndication_link:list"\n ).value,\n- [\'selected\']\n+ ["selected"],\n )\n \n def test_create_collection(self):\n- """Create collection and check if synPropertiesForm link is present.\n- """\n+ """Create collection and check if synPropertiesForm link is present."""\n # create collection\n- self.portal.invokeFactory(\'Collection\', \'collection\')\n+ self.portal.invokeFactory("Collection", "collection")\n self.portal.collection.query = [\n {\n "i": "portal_type",\n "o": "plone.app.querystring.operation.selection.any",\n- "v": ["News Item"]\n+ "v": ["News Item"],\n },\n {\n "i": "review_state",\n "o": "plone.app.querystring.operation.selection.any",\n- "v": ["published"]\n- }\n+ "v": ["published"],\n+ },\n ]\n transaction.commit()\n # Enable syndication\n- self.browser.open(\n- "%s/@@syndication-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.default_enabled:list\').value = [\'selected\']\n+ self.browser.open("%s/@@syndication-controlpanel" % self.portal_url)\n+ self.browser.getControl(name="form.widgets.default_enabled:list").value = [\n+ "selected"\n+ ]\n self.browser.getControl(\n- name=\'form.widgets.show_syndication_link:list\'\n- ).value = [\'selected\']\n- self.browser.getControl(\'Save\').click()\n- self.assertTrue(\'Changes saved\' in self.browser.contents)\n+ name="form.widgets.show_syndication_link:list"\n+ ).value = ["selected"]\n+ self.browser.getControl("Save").click()\n+ self.assertTrue("Changes saved" in self.browser.contents)\n \n- self.browser.open(self.portal_url + \'/collection\')\n- self.assertTrue(\'/RSS\' in self.browser.contents)\n+ self.browser.open(self.portal_url + "/collection")\n+ self.assertTrue("/RSS" in self.browser.contents)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_types.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_types.py\nindex 0cf2a5624f..565b8f8a04 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_types.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_types.py\n@@ -14,216 +14,179 @@ class TypesControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.types_url = "%s/@@content-controlpanel" % self.portal_url\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_types_control_panel_link(self):\n- self.browser.open(\n- "%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Editing\').click()\n+ self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n+ self.browser.getLink("Editing").click()\n \n def test_standard_type_select(self):\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n- self.assertIn(\'content-controlpanel\', self.browser.url)\n+ self.assertIn("content-controlpanel", self.browser.url)\n \n def test_standard_type_cancel(self):\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n- self.browser.getControl(\'Cancel\').click()\n- self.assertIn(\'@@overview-controlpanel\', self.browser.url)\n+ self.browser.getControl(name="type_id").value = ["Link"]\n+ self.browser.getControl("Cancel").click()\n+ self.assertIn("@@overview-controlpanel", self.browser.url)\n \n def test_standard_type_allow_commenting(self):\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n- self.browser.getControl(\'Allow comments\').selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl("Allow comments").selected = True\n+ self.browser.getControl("Save").click()\n \n # Check if settings got saved correctly\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n- self.assertIn(\'Globally addable\', self.browser.contents)\n- self.assertIn(\'Allow comments\', self.browser.contents)\n- self.assertEqual(\n- self.browser.getControl(\'Allow comments\').selected,\n- True\n- )\n- self.assertIn(\'Visible in searches\', self.browser.contents)\n+ self.assertIn("Globally addable", self.browser.contents)\n+ self.assertIn("Allow comments", self.browser.contents)\n+ self.assertEqual(self.browser.getControl("Allow comments").selected, True)\n+ self.assertIn("Visible in searches", self.browser.contents)\n self.assertIn(\n \' \',\n- self.browser.contents)\n+ self.browser.contents,\n+ )\n self.assertIn(\n \'Redirect immediately to link target\',\n- self.browser.contents\n+ self.browser.contents,\n )\n \n def test_standard_types_redirect_links(self):\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n- self.browser.getControl(\n- \'Redirect immediately to link target\'\n- ).selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl("Redirect immediately to link target").selected = True\n+ self.browser.getControl("Save").click()\n \n # Check if settings got saved correctly\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n- self.assertTrue(\n- \'Redirect immediately to link target\' in self.browser.contents\n- )\n+ self.assertTrue("Redirect immediately to link target" in self.browser.contents)\n self.assertEqual(\n- self.browser.getControl(\n- \'Redirect immediately to link target\').selected,\n- True\n+ self.browser.getControl("Redirect immediately to link target").selected,\n+ True,\n )\n \n def test_set_no_default_workflow(self):\n # references http://dev.plone.org/plone/ticket/11901\n self.browser.open(self.types_url)\n- self.browser.getControl(name="new_workflow").value = [\'[none]\']\n+ self.browser.getControl(name="new_workflow").value = ["[none]"]\n self.browser.getControl(name="form.button.Save").click()\n \n # Check that setting No workflow as default workflow doesn\'t break\n # break editing types\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n- self.assertIn(\'Globally addable\', self.browser.contents)\n- self.assertIn(\'Allow comments\', self.browser.contents)\n- self.assertIn(\'Visible in searches\', self.browser.contents)\n+ self.assertIn("Globally addable", self.browser.contents)\n+ self.assertIn("Allow comments", self.browser.contents)\n+ self.assertIn("Visible in searches", self.browser.contents)\n \n def test_disable_versioning_removes_behavior(self):\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Document\']\n+ self.browser.getControl(name="type_id").value = ["Document"]\n self.browser.getForm(action=self.types_url).submit()\n- self.browser.getControl(name=\'versionpolicy\').value = [\'off\']\n+ self.browser.getControl(name="versionpolicy").value = ["off"]\n self.browser.getControl(name="form.button.Save").click()\n \n portal_types = self.portal.portal_types\n doc_type = portal_types.Document\n- self.assertTrue(\n- \'plone.versioning\'\n- not in doc_type.behaviors) # noqa\n+ self.assertTrue("plone.versioning" not in doc_type.behaviors) # noqa\n \n def test_enable_versioning_behavior_on_document(self):\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Document\']\n+ self.browser.getControl(name="type_id").value = ["Document"]\n self.browser.getForm(action=self.types_url).submit()\n- self.browser.getControl(name=\'versionpolicy\').value = [\'off\']\n+ self.browser.getControl(name="versionpolicy").value = ["off"]\n self.browser.getControl(name="form.button.Save").click()\n \n portal_types = self.portal.portal_types\n doc_type = portal_types.Document\n- self.assertTrue(\n- \'plone.versioning\'\n- not in doc_type.behaviors) # noqa\n+ self.assertTrue("plone.versioning" not in doc_type.behaviors) # noqa\n \n- self.browser.getControl(name=\'versionpolicy\').value = [\'manual\']\n+ self.browser.getControl(name="versionpolicy").value = ["manual"]\n self.browser.getControl(name="form.button.Save").click()\n \n- self.assertTrue(\n- \'plone.versioning\'\n- in doc_type.behaviors)\n+ self.assertTrue("plone.versioning" in doc_type.behaviors)\n \n def test_enable_versioning_behavior_on_file(self):\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'File\']\n+ self.browser.getControl(name="type_id").value = ["File"]\n self.browser.getForm(action=self.types_url).submit()\n- self.browser.getControl(name=\'versionpolicy\').value = [\'off\']\n+ self.browser.getControl(name="versionpolicy").value = ["off"]\n self.browser.getForm(action=self.types_url).submit()\n \n portal_types = self.portal.portal_types\n file_type = portal_types.File\n \n # File has no Versioning and no Locking on default, but needs it\n- self.assertTrue(\n- \'plone.versioning\'\n- not in file_type.behaviors) # noqa\n- self.assertTrue(\n- \'plone.locking\'\n- not in file_type.behaviors) # noqa\n-\n- self.browser.getControl(name=\'versionpolicy\').value = [\'manual\']\n- self.browser.getControl(\'Save\').click()\n-\n- self.assertTrue(\n- \'plone.versioning\'\n- in file_type.behaviors)\n- self.assertTrue(\n- \'plone.locking\'\n- in file_type.behaviors)\n+ self.assertTrue("plone.versioning" not in file_type.behaviors) # noqa\n+ self.assertTrue("plone.locking" not in file_type.behaviors) # noqa\n+\n+ self.browser.getControl(name="versionpolicy").value = ["manual"]\n+ self.browser.getControl("Save").click()\n+\n+ self.assertTrue("plone.versioning" in file_type.behaviors)\n+ self.assertTrue("plone.locking" in file_type.behaviors)\n \n def test_dont_update_settings_when_switch_types(self):\n # First of all, set a default\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n- self.browser.getControl(\n- \'Redirect immediately to link target\'\n- ).selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl("Redirect immediately to link target").selected = True\n+ self.browser.getControl("Save").click()\n \n # Then switch the type\n- self.browser.getControl(name=\'type_id\').value = [\'Document\']\n+ self.browser.getControl(name="type_id").value = ["Document"]\n self.browser.getForm(action=self.types_url).submit()\n- self.assertFalse(\n- \'Redirect immediately to link target\' in self.browser.contents\n- )\n+ self.assertFalse("Redirect immediately to link target" in self.browser.contents)\n \n # Go back to the link, and check the value\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n \n- self.assertTrue(\n- \'Redirect immediately to link target\' in self.browser.contents\n- )\n+ self.assertTrue("Redirect immediately to link target" in self.browser.contents)\n self.assertEqual(\n- self.browser.getControl(\n- \'Redirect immediately to link target\').selected,\n- True\n+ self.browser.getControl("Redirect immediately to link target").selected,\n+ True,\n )\n \n def test_dont_update_redirect_links_when_not_in_link_settings(self):\n # First of all, set a default\n self.browser.open(self.types_url)\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n- self.browser.getControl(\n- \'Redirect immediately to link target\'\n- ).selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl("Redirect immediately to link target").selected = True\n+ self.browser.getControl("Save").click()\n \n # Then switch the type\n- self.browser.getControl(name=\'type_id\').value = [\'Document\']\n+ self.browser.getControl(name="type_id").value = ["Document"]\n self.browser.getForm(action=self.types_url).submit()\n- self.assertFalse(\n- \'Redirect immediately to link target\' in self.browser.contents\n- )\n- self.browser.getControl(\'Save\').click()\n+ self.assertFalse("Redirect immediately to link target" in self.browser.contents)\n+ self.browser.getControl("Save").click()\n \n # Go back to the link, and check the value\n- self.browser.getControl(name=\'type_id\').value = [\'Link\']\n+ self.browser.getControl(name="type_id").value = ["Link"]\n self.browser.getForm(action=self.types_url).submit()\n \n- self.assertTrue(\n- \'Redirect immediately to link target\' in self.browser.contents\n- )\n+ self.assertTrue("Redirect immediately to link target" in self.browser.contents)\n self.assertEqual(\n- self.browser.getControl(\n- \'Redirect immediately to link target\').selected,\n- True\n+ self.browser.getControl("Redirect immediately to link target").selected,\n+ True,\n )\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups.py\nindex ad954f6288..6c9a881970 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups.py\n@@ -17,128 +17,280 @@ class UserGroupsControlPanelFunctionalTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def _generateGroups(self):\n- groupsTool = getToolByName(self.portal, \'portal_groups\')\n+ groupsTool = getToolByName(self.portal, "portal_groups")\n self.groups = [\n- {\'id\': \'group1\', \'title\': "Group 1"},\n- {\'id\': \'group2\', \'title\': "Group 2"},\n- {\'id\': \'group3\', \'title\': "Group 3 accentu\xc3\xa9"}\n+ {"id": "group1", "title": "Group 1"},\n+ {"id": "group2", "title": "Group 2"},\n+ {"id": "group3", "title": "Group 3 accentu\xc3\xa9"},\n ]\n for group in self.groups:\n- groupsTool.addGroup(group[\'id\'], [], [], title=group[\'title\'])\n+ groupsTool.addGroup(group["id"], [], [], title=group["title"])\n \n def _generateUsers(self):\n self.members = [\n- {\'username\': \'DIispfuF\', \'fullname\': \'Kevin Hughes\',\n- \'email\': \'DIispfuF@example.com\'},\n- {\'username\': \'enTHXigm\', \'fullname\': \'Richard Ramirez\',\n- \'email\': \'enTHXigm@example.com\'},\n- {\'username\': \'q7UsYcrT\', \'fullname\': \'Kyle Brown\',\n- \'email\': \'q7UsYcrT@example.com\'},\n- {\'username\': \'j5g0xPmr\', \'fullname\': \'Julian Green\',\n- \'email\': \'j5g0xPmr@example.com\'},\n- {\'username\': \'o6Sx4It3\', \'fullname\': \'Makayla Coleman\',\n- \'email\': \'o6Sx4It3@example.com\'},\n- {\'username\': \'SLUhquYa\', \'fullname\': \'Sean Foster\',\n- \'email\': \'SLUhquYa@example.com\'},\n- {\'username\': \'nHWl3Ita\', \'fullname\': \'Molly Martin\',\n- \'email\': \'nHWl3Ita@example.com\'},\n- {\'username\': \'xdkpCKmX\', \'fullname\': \'Jordan Thompson\',\n- \'email\': \'xdkpCKmX@example.com\'},\n- {\'username\': \'p8H6CicB\', \'fullname\': \'Tyler Rivera\',\n- \'email\': \'p8H6CicB@example.com\'},\n- {\'username\': \'T6vdBXbD\', \'fullname\': \'Megan Murphy\',\n- \'email\': \'T6vdBXbD@example.com\'},\n- {\'username\': \'DohPmgIa\', \'fullname\': \'Gracie Diaz\',\n- \'email\': \'DohPmgIa@example.com\'},\n- {\'username\': \'CqHWi65B\', \'fullname\': \'Rachel Morgan\',\n- \'email\': \'CqHWi65B@example.com\'},\n- {\'username\': \'uHFQ7qk4\', \'fullname\': \'Maya Price\',\n- \'email\': \'uHFQ7qk4@example.com\'},\n- {\'username\': \'BlXLQh7r\', \'fullname\': \'Blake Jenkins\',\n- \'email\': \'BlXLQh7r@example.com\'},\n- {\'username\': \'FCrWUiSY\', \'fullname\': \'Owen Ramirez\',\n- \'email\': \'FCrWUiSY@example.com\'},\n- {\'username\': \'bX3PqgHK\', \'fullname\': \'Owen Cook\',\n- \'email\': \'bX3PqgHK@example.com\'},\n- {\'username\': \'sD35vVl0\', \'fullname\': \'Jayden Hill\',\n- \'email\': \'sD35vVl0@example.com\'},\n- {\'username\': \'mfOcjXAG\', \'fullname\': \'Joseph Ramirez\',\n- \'email\': \'mfOcjXAG@example.com\'},\n- {\'username\': \'GAJtdYbM\', \'fullname\': \'Nathan Young\',\n- \'email\': \'GAJtdYbM@example.com\'},\n- {\'username\': \'E1OWG6bv\', \'fullname\': \'Kaitlyn Hernandez\',\n- \'email\': \'E1OWG6bv@example.com\'},\n- {\'username\': \'BqOX2sCm\', \'fullname\': \'Faith Price\',\n- \'email\': \'BqOX2sCm@example.com\'},\n- {\'username\': \'tyOxRnml\', \'fullname\': \'Sofia Williams\',\n- \'email\': \'5yOxRjtl@example.com\'},\n- {\'username\': \'fVcumDNl\', \'fullname\': \'David Sanders\',\n- \'email\': \'fVcumDNl@example.com\'},\n- {\'username\': \'Ge1hqdEI\', \'fullname\': \'Jack Simmons\',\n- \'email\': \'Ge1hqdEI@example.com\'},\n- {\'username\': \'o2CqT7kG\', \'fullname\': \'Cole Howard\',\n- \'email\': \'o2CqT7kG@example.com\'},\n- {\'username\': \'mpGtfNl6\', \'fullname\': \'Rachel Miller\',\n- \'email\': \'mpGtfNl6@example.com\'},\n- {\'username\': \'RGrpWiBg\', \'fullname\': \'Henry Patterson\',\n- \'email\': \'RGrpWiBg@example.com\'},\n- {\'username\': \'Bufmi0YS\', \'fullname\': \'Avery Cooper\',\n- \'email\': \'Bufmi0YS@example.com\'},\n- {\'username\': \'J7NvbjYd\', \'fullname\': \'Sydney Bennett\',\n- \'email\': \'J7NvbjYd@example.com\'},\n- {\'username\': \'u5Xem8U1\', \'fullname\': \'Daniel Johnson\',\n- \'email\': \'u5Xem8U1@example.com\'},\n- {\'username\': \'TWrMCLIo\', \'fullname\': \'Autumn Brooks\',\n- \'email\': \'0VrMCLIo@example.com\'},\n- {\'username\': \'FElYwiIr\', \'fullname\': \'Alexandra Nelson\',\n- \'email\': \'FElYwiIr@example.com\'},\n- {\'username\': \'teK6pkhc\', \'fullname\': \'Brian Simmons\',\n- \'email\': \'0eK6pkhc@example.com\'},\n- {\'username\': \'RwAO2YPa\', \'fullname\': \'Kevin Hughes\',\n- \'email\': \'gracie@example.com\'},\n- {\'username\': \'nlBMw26i\', \'fullname\': \'Sydney Evans\',\n- \'email\': \'nlBMw26i@example.com\'},\n- {\'username\': \'Ahr3EiRC\', \'fullname\': \'Emma Brown\',\n- \'email\': \'Ahr3EiRC@example.com\'},\n- {\'username\': \'NhuU0Y5x\', \'fullname\': \'Lauren Martin\',\n- \'email\': \'NhuU0Y5x@example.com\'},\n- {\'username\': \'j2R3mKQg\', \'fullname\': \'Isabelle Russell\',\n- \'email\': \'j2R3mKQg@example.com\'},\n- {\'username\': \'qOmK0iCN\', \'fullname\': \'Anna Baker\',\n- \'email\': \'qOmK0iCN@example.com\'},\n- {\'username\': \'uQbVOgo7\', \'fullname\': \'Brady Watson\',\n- \'email\': \'uQbVOgo7@example.com\'},\n- {\'username\': \'oLDCaQfW\', \'fullname\': \'Kaitlyn Robinson\',\n- \'email\': \'oLDCaQfW@example.com\'},\n- {\'username\': \'osYHeFD1\', \'fullname\': \'Riley Richardson\',\n- \'email\': \'osYHeFD1@example.com\'},\n- {\'username\': \'i4pHduDY\', \'fullname\': \'Kayla Sanders\',\n- \'email\': \'i4pHduDY@example.com\'},\n- {\'username\': \'BvyX6qF3\', \'fullname\': \'Sara Richardson\',\n- \'email\': \'BvyX6qF3@example.com\'},\n- {\'username\': \'a3EpwDYj\', \'fullname\': \'Trinity Gonzales\',\n- \'email\': \'a3EpwDYj@example.com\'},\n- {\'username\': \'JDMseWdt\', \'fullname\': \'Madeline Garcia\',\n- \'email\': \'JDMseWdt@example.com\'},\n- {\'username\': \'lPCYBvoi\', \'fullname\': \'Brian Gray\',\n- \'email\': \'lPCYBvoi@example.com\'},\n- {\'username\': \'AByCsRQ3\', \'fullname\': \'Victoria Perez\',\n- \'email\': \'AByCsRQ3@example.com\'},\n- {\'username\': \'CH7uVlNy\', \'fullname\': \'Charles Rodriguez\',\n- \'email\': \'5H7uVlNy@example.com\'},\n- {\'username\': \'XYsmd7ux\', \'fullname\': \'Abigail Simmons\',\n- \'email\': \'XYsmd7ux@example.com\'},\n- {\'username\': \'DfaA1wqC3\', \'fullname\': \'\xc3\x89milie Richard\',\n- \'email\': \'DfaA1wqC3@example.com\'},\n+ {\n+ "username": "DIispfuF",\n+ "fullname": "Kevin Hughes",\n+ "email": "DIispfuF@example.com",\n+ },\n+ {\n+ "username": "enTHXigm",\n+ "fullname": "Richard Ramirez",\n+ "email": "enTHXigm@example.com",\n+ },\n+ {\n+ "username": "q7UsYcrT",\n+ "fullname": "Kyle Brown",\n+ "email": "q7UsYcrT@example.com",\n+ },\n+ {\n+ "username": "j5g0xPmr",\n+ "fullname": "Julian Green",\n+ "email": "j5g0xPmr@example.com",\n+ },\n+ {\n+ "username": "o6Sx4It3",\n+ "fullname": "Makayla Coleman",\n+ "email": "o6Sx4It3@example.com",\n+ },\n+ {\n+ "username": "SLUhquYa",\n+ "fullname": "Sean Foster",\n+ "email": "SLUhquYa@example.com",\n+ },\n+ {\n+ "username": "nHWl3Ita",\n+ "fullname": "Molly Martin",\n+ "email": "nHWl3Ita@example.com",\n+ },\n+ {\n+ "username": "xdkpCKmX",\n+ "fullname": "Jordan Thompson",\n+ "email": "xdkpCKmX@example.com",\n+ },\n+ {\n+ "username": "p8H6CicB",\n+ "fullname": "Tyler Rivera",\n+ "email": "p8H6CicB@example.com",\n+ },\n+ {\n+ "username": "T6vdBXbD",\n+ "fullname": "Megan Murphy",\n+ "email": "T6vdBXbD@example.com",\n+ },\n+ {\n+ "username": "DohPmgIa",\n+ "fullname": "Gracie Diaz",\n+ "email": "DohPmgIa@example.com",\n+ },\n+ {\n+ "username": "CqHWi65B",\n+ "fullname": "Rachel Morgan",\n+ "email": "CqHWi65B@example.com",\n+ },\n+ {\n+ "username": "uHFQ7qk4",\n+ "fullname": "Maya Price",\n+ "email": "uHFQ7qk4@example.com",\n+ },\n+ {\n+ "username": "BlXLQh7r",\n+ "fullname": "Blake Jenkins",\n+ "email": "BlXLQh7r@example.com",\n+ },\n+ {\n+ "username": "FCrWUiSY",\n+ "fullname": "Owen Ramirez",\n+ "email": "FCrWUiSY@example.com",\n+ },\n+ {\n+ "username": "bX3PqgHK",\n+ "fullname": "Owen Cook",\n+ "email": "bX3PqgHK@example.com",\n+ },\n+ {\n+ "username": "sD35vVl0",\n+ "fullname": "Jayden Hill",\n+ "email": "sD35vVl0@example.com",\n+ },\n+ {\n+ "username": "mfOcjXAG",\n+ "fullname": "Joseph Ramirez",\n+ "email": "mfOcjXAG@example.com",\n+ },\n+ {\n+ "username": "GAJtdYbM",\n+ "fullname": "Nathan Young",\n+ "email": "GAJtdYbM@example.com",\n+ },\n+ {\n+ "username": "E1OWG6bv",\n+ "fullname": "Kaitlyn Hernandez",\n+ "email": "E1OWG6bv@example.com",\n+ },\n+ {\n+ "username": "BqOX2sCm",\n+ "fullname": "Faith Price",\n+ "email": "BqOX2sCm@example.com",\n+ },\n+ {\n+ "username": "tyOxRnml",\n+ "fullname": "Sofia Williams",\n+ "email": "5yOxRjtl@example.com",\n+ },\n+ {\n+ "username": "fVcumDNl",\n+ "fullname": "David Sanders",\n+ "email": "fVcumDNl@example.com",\n+ },\n+ {\n+ "username": "Ge1hqdEI",\n+ "fullname": "Jack Simmons",\n+ "email": "Ge1hqdEI@example.com",\n+ },\n+ {\n+ "username": "o2CqT7kG",\n+ "fullname": "Cole Howard",\n+ "email": "o2CqT7kG@example.com",\n+ },\n+ {\n+ "username": "mpGtfNl6",\n+ "fullname": "Rachel Miller",\n+ "email": "mpGtfNl6@example.com",\n+ },\n+ {\n+ "username": "RGrpWiBg",\n+ "fullname": "Henry Patterson",\n+ "email": "RGrpWiBg@example.com",\n+ },\n+ {\n+ "username": "Bufmi0YS",\n+ "fullname": "Avery Cooper",\n+ "email": "Bufmi0YS@example.com",\n+ },\n+ {\n+ "username": "J7NvbjYd",\n+ "fullname": "Sydney Bennett",\n+ "email": "J7NvbjYd@example.com",\n+ },\n+ {\n+ "username": "u5Xem8U1",\n+ "fullname": "Daniel Johnson",\n+ "email": "u5Xem8U1@example.com",\n+ },\n+ {\n+ "username": "TWrMCLIo",\n+ "fullname": "Autumn Brooks",\n+ "email": "0VrMCLIo@example.com",\n+ },\n+ {\n+ "username": "FElYwiIr",\n+ "fullname": "Alexandra Nelson",\n+ "email": "FElYwiIr@example.com",\n+ },\n+ {\n+ "username": "teK6pkhc",\n+ "fullname": "Brian Simmons",\n+ "email": "0eK6pkhc@example.com",\n+ },\n+ {\n+ "username": "RwAO2YPa",\n+ "fullname": "Kevin Hughes",\n+ "email": "gracie@example.com",\n+ },\n+ {\n+ "username": "nlBMw26i",\n+ "fullname": "Sydney Evans",\n+ "email": "nlBMw26i@example.com",\n+ },\n+ {\n+ "username": "Ahr3EiRC",\n+ "fullname": "Emma Brown",\n+ "email": "Ahr3EiRC@example.com",\n+ },\n+ {\n+ "username": "NhuU0Y5x",\n+ "fullname": "Lauren Martin",\n+ "email": "NhuU0Y5x@example.com",\n+ },\n+ {\n+ "username": "j2R3mKQg",\n+ "fullname": "Isabelle Russell",\n+ "email": "j2R3mKQg@example.com",\n+ },\n+ {\n+ "username": "qOmK0iCN",\n+ "fullname": "Anna Baker",\n+ "email": "qOmK0iCN@example.com",\n+ },\n+ {\n+ "username": "uQbVOgo7",\n+ "fullname": "Brady Watson",\n+ "email": "uQbVOgo7@example.com",\n+ },\n+ {\n+ "username": "oLDCaQfW",\n+ "fullname": "Kaitlyn Robinson",\n+ "email": "oLDCaQfW@example.com",\n+ },\n+ {\n+ "username": "osYHeFD1",\n+ "fullname": "Riley Richardson",\n+ "email": "osYHeFD1@example.com",\n+ },\n+ {\n+ "username": "i4pHduDY",\n+ "fullname": "Kayla Sanders",\n+ "email": "i4pHduDY@example.com",\n+ },\n+ {\n+ "username": "BvyX6qF3",\n+ "fullname": "Sara Richardson",\n+ "email": "BvyX6qF3@example.com",\n+ },\n+ {\n+ "username": "a3EpwDYj",\n+ "fullname": "Trinity Gonzales",\n+ "email": "a3EpwDYj@example.com",\n+ },\n+ {\n+ "username": "JDMseWdt",\n+ "fullname": "Madeline Garcia",\n+ "email": "JDMseWdt@example.com",\n+ },\n+ {\n+ "username": "lPCYBvoi",\n+ "fullname": "Brian Gray",\n+ "email": "lPCYBvoi@example.com",\n+ },\n+ {\n+ "username": "AByCsRQ3",\n+ "fullname": "Victoria Perez",\n+ "email": "AByCsRQ3@example.com",\n+ },\n+ {\n+ "username": "CH7uVlNy",\n+ "fullname": "Charles Rodriguez",\n+ "email": "5H7uVlNy@example.com",\n+ },\n+ {\n+ "username": "XYsmd7ux",\n+ "fullname": "Abigail Simmons",\n+ "email": "XYsmd7ux@example.com",\n+ },\n+ {\n+ "username": "DfaA1wqC3",\n+ "fullname": "\xc3\x89milie Richard",\n+ "email": "DfaA1wqC3@example.com",\n+ },\n ]\n- rtool = getToolByName(self.portal, \'portal_registration\')\n+ rtool = getToolByName(self.portal, "portal_registration")\n for member in self.members:\n- rtool.addMember(member[\'username\'],\n- \'somepassword\', properties=member)\n+ rtool.addMember(member["username"], "somepassword", properties=member)\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n self.portal_url = self.portal.absolute_url()\n self.users_url = "%s/@@usergroup-userprefs" % self.portal_url\n self.groups_url = "%s/@@usergroup-groupprefs" % self.portal_url\n@@ -151,262 +303,250 @@ def setUp(self):\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n \n def test_usergroups_control_panel_link_users(self):\n self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Users\').click()\n- self.assertEqual(\n- self.browser.url,\n- self.users_url\n- )\n+ self.browser.getLink("Users").click()\n+ self.assertEqual(self.browser.url, self.users_url)\n+\n def test_usergroups_control_panel_link_users(self):\n self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Groups\').click()\n- self.assertEqual(\n- self.browser.url,\n- self.groups_url\n- )\n+ self.browser.getLink("Groups").click()\n+ self.assertEqual(self.browser.url, self.groups_url)\n \n def test_usergroups_control_panel_link_settings(self):\n self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'User and Group Settings\').click()\n- self.assertEqual(\n- self.browser.url,\n- self.settings_url\n- )\n+ self.browser.getLink("User and Group Settings").click()\n+ self.assertEqual(self.browser.url, self.settings_url)\n \n def test_usergroups_control_panel_link_settings(self):\n self.browser.open("%s/@@overview-controlpanel" % self.portal_url)\n- self.browser.getLink(\'Member Fields\').click()\n- self.assertEqual(\n- self.browser.url,\n- self.memberfields_url\n- )\n+ self.browser.getLink("Member Fields").click()\n+ self.assertEqual(self.browser.url, self.memberfields_url)\n \n def test_user_search_by_name(self):\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'Richard\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertIn(\'Richard Ramirez\', self.browser.contents)\n- self.assertIn(\'Sara Richardson\', self.browser.contents)\n- self.assertIn(\'\xc3\x89milie Richard\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "Richard"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertIn("Richard Ramirez", self.browser.contents)\n+ self.assertIn("Sara Richardson", self.browser.contents)\n+ self.assertIn("\xc3\x89milie Richard", self.browser.contents)\n \n def test_user_search_by_name_accent(self):\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'\xc3\x89milie\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertIn(\'\xc3\x89milie Richard\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "\xc3\x89milie"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertIn("\xc3\x89milie Richard", self.browser.contents)\n \n def test_user_search_by_id(self):\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'TWrMCLIo\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertIn(\'Autumn Brooks\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "TWrMCLIo"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertIn("Autumn Brooks", self.browser.contents)\n \n def test_user_search_by_mail(self):\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'DohPmgIa@\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertIn(\'Gracie Diaz\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "DohPmgIa@"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertIn("Gracie Diaz", self.browser.contents)\n \n def test_user_show_all(self):\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'form.button.FindAll\').click()\n+ self.browser.getControl(name="form.button.FindAll").click()\n \n # Check that first 10 members (sorted by fullname) are shown.\n for member in sorted(\n- self.members, key=lambda k: normalizeString(k[\'fullname\'])\n+ self.members, key=lambda k: normalizeString(k["fullname"])\n )[:10]:\n- self.assertIn(member[\'fullname\'], self.browser.contents)\n+ self.assertIn(member["fullname"], self.browser.contents)\n \n def test_user_show_all_with_search_term(self):\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'no-user\'\n- self.browser.getControl(name=\'form.button.FindAll\').click()\n+ self.browser.getControl(name="searchstring").value = "no-user"\n+ self.browser.getControl(name="form.button.FindAll").click()\n \n # Check that all members is shown and search term is ignored\n- self.assertIn(\'Avery Cooper\', self.browser.contents)\n+ self.assertIn("Avery Cooper", self.browser.contents)\n \n def test_user_add_new_link(self):\n self.browser.open(self.users_url)\n- self.browser.getLink(id=\'add-user\').click()\n- self.assertEqual(\n- self.browser.url,\n- "%s/@@new-user" % self.portal_url\n- )\n+ self.browser.getLink(id="add-user").click()\n+ self.assertEqual(self.browser.url, "%s/@@new-user" % self.portal_url)\n \n def test_user_modify_roles(self):\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'TWrMCLIo\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n+ self.browser.getControl(name="searchstring").value = "TWrMCLIo"\n+ self.browser.getControl(name="form.button.Search").click()\n \n # Check that contributor role is not enabled and enable it\n- self.assertFalse(self.browser.getControl(\n- name=\'users.roles:list:records\'\n- ).getControl(value=\'Contributor\').selected)\n- self.browser.getControl(\n- name=\'users.roles:list:records\'\n- ).getControl(value=\'Contributor\').selected = True\n- self.browser.getControl(name=\'form.button.Modify\').click()\n+ self.assertFalse(\n+ self.browser.getControl(name="users.roles:list:records")\n+ .getControl(value="Contributor")\n+ .selected\n+ )\n+ self.browser.getControl(name="users.roles:list:records").getControl(\n+ value="Contributor"\n+ ).selected = True\n+ self.browser.getControl(name="form.button.Modify").click()\n \n # Check that contributor role is now enabled for this user\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'TWrMCLIo\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertTrue(self.browser.getControl(\n- name=\'users.roles:list:records\'\n- ).getControl(value=\'Contributor\').selected)\n+ self.browser.getControl(name="searchstring").value = "TWrMCLIo"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertTrue(\n+ self.browser.getControl(name="users.roles:list:records")\n+ .getControl(value="Contributor")\n+ .selected\n+ )\n \n def test_user_delete(self):\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'TWrMCLIo\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertIn(\'Autumn Brooks\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "TWrMCLIo"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertIn("Autumn Brooks", self.browser.contents)\n \n # Delete user\n- self.browser.getControl(name=\'delete:list\').getControl(\n- value=\'TWrMCLIo\').selected = True\n- self.browser.getControl(name=\'form.button.Modify\').click()\n+ self.browser.getControl(name="delete:list").getControl(\n+ value="TWrMCLIo"\n+ ).selected = True\n+ self.browser.getControl(name="form.button.Modify").click()\n \n # Check that user does not exist anymore\n- self.browser.getControl(name=\'searchstring\').value = \'TWrMCLIo\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertNotIn(\'Autumn Brooks\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "TWrMCLIo"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertNotIn("Autumn Brooks", self.browser.contents)\n \n def test_groups_search_by_id(self):\n self.browser.open(self.groups_url)\n- self.browser.getControl(name=\'searchstring\').value = \'group1\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertIn(\'Group 1\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "group1"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertIn("Group 1", self.browser.contents)\n \n def test_groups_search_by_name(self):\n self.browser.open(self.groups_url)\n- self.browser.getControl(name=\'searchstring\').value = \'Group 3 accentu\xc3\xa9\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.assertIn(\'Group 3 accentu\xc3\xa9\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "Group 3 accentu\xc3\xa9"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.assertIn("Group 3 accentu\xc3\xa9", self.browser.contents)\n \n def test_groups_modify_roles(self):\n self.browser.open(self.groups_url)\n- self.browser.getControl(name=\'searchstring\').value = \'group1\'\n+ self.browser.getControl(name="searchstring").value = "group1"\n \n # Check that role is not selected yet and then select it and apply it.\n- form = self.browser.getForm(id=\'groups_search\')\n- ctrls = form._form.fields.get(\'group_group1:list\')\n+ form = self.browser.getForm(id="groups_search")\n+ ctrls = form._form.fields.get("group_group1:list")\n roles = [ctrl._value for ctrl in ctrls]\n- expected = \'Site Administrator\'\n+ expected = "Site Administrator"\n self.assertIn(expected, roles)\n idx = roles.index(expected)\n self.assertFalse(ctrls[idx].checked)\n ctrls[idx].checked = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl("Save").click()\n \n # Check that role is now selected\n- form = self.browser.getForm(id=\'groups_search\')\n- ctrl = form._form.get(\'group_group1:list\', index=idx)\n+ form = self.browser.getForm(id="groups_search")\n+ ctrl = form._form.get("group_group1:list", index=idx)\n self.assertEqual(ctrl._value, expected)\n self.assertTrue(ctrl.checked)\n \n def test_groups_delete_group(self):\n self.browser.open(self.groups_url)\n- self.browser.getControl(name=\'searchstring\').value = \'group1\'\n+ self.browser.getControl(name="searchstring").value = "group1"\n \n # Delete a group\n- self.browser.getControl(\n- name=\'delete:list\'\n- ).getControl(value=\'group1\').selected = True\n- self.browser.getControl(name=\'form.button.Modify\').click()\n+ self.browser.getControl(name="delete:list").getControl(\n+ value="group1"\n+ ).selected = True\n+ self.browser.getControl(name="form.button.Modify").click()\n \n # Check that group doesn\'t exist anymore\n- self.browser.getControl(name=\'searchstring\').value = \'group1\'\n- self.assertNotIn(\'Group 1\', self.browser.contents)\n+ self.browser.getControl(name="searchstring").value = "group1"\n+ self.assertNotIn("Group 1", self.browser.contents)\n \n def test_groups_show_all(self):\n self.browser.open(self.groups_url)\n- self.browser.getControl(name=\'form.button.FindAll\').click()\n+ self.browser.getControl(name="form.button.FindAll").click()\n \n for group in self.groups:\n- self.assertIn(group[\'title\'], self.browser.contents)\n+ self.assertIn(group["title"], self.browser.contents)\n \n def test_group_add_users(self):\n self.browser.open(self.groups_url)\n- self.browser.getLink(\'Group 1 (group1)\').click()\n+ self.browser.getLink("Group 1 (group1)").click()\n self.assertIn(\n- \'There is no group or user attached to this group.\',\n- self.browser.contents\n+ "There is no group or user attached to this group.", self.browser.contents\n )\n \n # Add user (Autumn Brooks) to selected group (Group 1)\n- self.browser.getControl(name=\'searchstring\').value = \'TWrMCLIo\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.browser.getControl(name=\'add:list\').getControl(\n- value=\'TWrMCLIo\').selected = True\n+ self.browser.getControl(name="searchstring").value = "TWrMCLIo"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.browser.getControl(name="add:list").getControl(\n+ value="TWrMCLIo"\n+ ).selected = True\n \n # Check that user is now part of the group\n- self.browser.getControl(\n- \'Add selected groups and users to this group\').click()\n- self.assertIn(\'Autumn Brooks\', self.browser.contents)\n+ self.browser.getControl("Add selected groups and users to this group").click()\n+ self.assertIn("Autumn Brooks", self.browser.contents)\n \n def test_group_add_group(self):\n self.browser.open(self.groups_url)\n- self.browser.getLink(\'Group 1 (group1)\').click()\n+ self.browser.getLink("Group 1 (group1)").click()\n self.assertIn(\n- \'There is no group or user attached to this group.\',\n- self.browser.contents\n+ "There is no group or user attached to this group.", self.browser.contents\n )\n \n # Add group2 to selected group 1\n- self.browser.getControl(name=\'searchstring\').value = \'group2\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.browser.getControl(name=\'add:list\').getControl(\n- value=\'group2\').selected = True\n+ self.browser.getControl(name="searchstring").value = "group2"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.browser.getControl(name="add:list").getControl(\n+ value="group2"\n+ ).selected = True\n \n # Check that group is now part of the group\n- self.browser.getControl(\n- \'Add selected groups and users to this group\').click()\n- self.assertIn(\'Group 2\', self.browser.contents)\n+ self.browser.getControl("Add selected groups and users to this group").click()\n+ self.assertIn("Group 2", self.browser.contents)\n \n # Check that you can still add a user too. This failed at some point:\n # https://github.com/plone/Products.CMFPlone/issues/3048\n # Add user (Autumn Brooks) to selected group (Group 1)\n- self.browser.getControl(name=\'searchstring\').value = \'TWrMCLIo\'\n- self.browser.getControl(name=\'form.button.Search\').click()\n- self.browser.getControl(name=\'add:list\').getControl(\n- value=\'TWrMCLIo\').selected = True\n- self.browser.getControl(\n- \'Add selected groups and users to this group\').click()\n+ self.browser.getControl(name="searchstring").value = "TWrMCLIo"\n+ self.browser.getControl(name="form.button.Search").click()\n+ self.browser.getControl(name="add:list").getControl(\n+ value="TWrMCLIo"\n+ ).selected = True\n+ self.browser.getControl("Add selected groups and users to this group").click()\n \n # Check that both group and user are now part of the group\n self.browser.open(self.groups_url)\n- self.browser.getLink(\'Group 1 (group1)\').click()\n- self.assertIn(\'Autumn Brooks\', self.browser.contents)\n- self.assertIn(\'Group 2\', self.browser.contents)\n+ self.browser.getLink("Group 1 (group1)").click()\n+ self.assertIn("Autumn Brooks", self.browser.contents)\n+ self.assertIn("Group 2", self.browser.contents)\n \n def test_usergroups_settings_many_users(self):\n self.browser.open("%s/@@usergroup-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.many_users:list\'\n- ).controls[0].selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl(name="form.widgets.many_users:list").controls[\n+ 0\n+ ].selected = True\n+ self.browser.getControl("Save").click()\n \n # Check that show all button for users is no longer available\n self.browser.open(self.users_url)\n- self.assertNotIn(\'Show all\', self.browser.contents)\n+ self.assertNotIn("Show all", self.browser.contents)\n \n # Check that empty search does not trigger show all\n self.browser.open(self.users_url)\n- self.browser.getControl(name=\'searchstring\').value = \'\'\n+ self.browser.getControl(name="searchstring").value = ""\n \n def test_usergroups_settings_many_groups(self):\n self.browser.open("%s/@@usergroup-controlpanel" % self.portal_url)\n- self.browser.getControl(\n- name=\'form.widgets.many_groups:list\'\n- ).controls[0].selected = True\n- self.browser.getControl(\'Save\').click()\n+ self.browser.getControl(name="form.widgets.many_groups:list").controls[\n+ 0\n+ ].selected = True\n+ self.browser.getControl("Save").click()\n \n # Check that show all button for groups is no longer available\n self.browser.open(self.groups_url)\n- self.assertNotIn(\'Show all\', self.browser.contents)\n- self.assertNotIn(\'DIispfuF\', self.browser.contents)\n+ self.assertNotIn("Show all", self.browser.contents)\n+ self.assertNotIn("DIispfuF", self.browser.contents)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups_siteadmin_role.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups_siteadmin_role.py\nindex 3000ecc0d3..ec54a9c863 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups_siteadmin_role.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_usergroups_siteadmin_role.py\n@@ -16,38 +16,36 @@\n \n \n class TestSiteAdministratorRoleFunctional(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def _generateUsers(self):\n- rtool = getToolByName(self.portal, \'portal_registration\')\n- rtool.addMember(\'DIispfuF\', TEST_USER_PASSWORD, [\'Member\'], [])\n- rtool.addMember(\'siteadmin\', TEST_USER_PASSWORD, [\'Site Administrator\'], [])\n- rtool.addMember(\'root\', TEST_USER_PASSWORD, [\'Manager\'], [])\n+ rtool = getToolByName(self.portal, "portal_registration")\n+ rtool.addMember("DIispfuF", TEST_USER_PASSWORD, ["Member"], [])\n+ rtool.addMember("siteadmin", TEST_USER_PASSWORD, ["Site Administrator"], [])\n+ rtool.addMember("root", TEST_USER_PASSWORD, ["Manager"], [])\n \n def setUp(self):\n- self.app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n self.portal_url = self.portal.absolute_url()\n self.usergroups_url = "%s/@@usergroup-userprefs" % self.portal_url\n self.groups_url = "%s/@@usergroup-groupprefs" % self.portal_url\n self._generateUsers()\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n transaction.commit()\n \n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {TEST_USER_ID}:{TEST_USER_PASSWORD}\'\n+ "Authorization", f"Basic {TEST_USER_ID}:{TEST_USER_PASSWORD}"\n )\n- self.normal_user = \'DIispfuF\'\n+ self.normal_user = "DIispfuF"\n \n def _get_authenticator(self, browser=None):\n if not browser:\n browser = self.browser\n- return browser.getControl(name=\'_authenticator\').value\n+ return browser.getControl(name="_authenticator").value\n \n def _simplify_white_space(self, text):\n """For easier testing we replace all white space with one space.\n@@ -64,158 +62,155 @@ def _simplify_white_space(self, text):\n \n Bar
\n """\n- text = re.sub(r\'\\s*<\\s*\', \'<\', text)\n- text = re.sub(r\'\\s*>\\s*\', \'>\', text)\n- text = re.sub(r\'\\s+\', \' \', text)\n+ text = re.sub(r"\\s*<\\s*", "<", text)\n+ text = re.sub(r"\\s*>\\s*", ">", text)\n+ text = re.sub(r"\\s+", " ", text)\n return text\n \n def testControlPanelOverview(self):\n # make sure we can view the Site Setup page,\n # at both old and new URLs\n- self.assertFalse(self.portal.restrictedTraverse(\'plone_control_panel\', False))\n- view = self.portal.restrictedTraverse(\'overview-controlpanel\')\n+ self.assertFalse(self.portal.restrictedTraverse("plone_control_panel", False))\n+ view = self.portal.restrictedTraverse("overview-controlpanel")\n self.assertTrue(view())\n \n def testUserManagerRoleCheckboxIsDisabledForNonManagers(self):\n- login(self.portal, \'siteadmin\')\n- view = self.portal.restrictedTraverse(\'@@usergroup-userprefs\')\n+ login(self.portal, "siteadmin")\n+ view = self.portal.restrictedTraverse("@@usergroup-userprefs")\n contents = view()\n- self.assertTrue(\' \' in contents)\n+ self.assertTrue(\n+ \' \' in contents\n+ )\n \n def testManagerCanDelegateManagerRoleForUsers(self):\n # a user with the Manager role can grant the Manager role\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n self.browser.open(self.usergroups_url)\n form = {\n- \'_authenticator\': self._get_authenticator(),\n- \'users.id:records\': self.normal_user,\n- \'users.roles:list:records\': \'Manager\',\n- \'form.button.Modify\': \'Save\',\n- \'form.submitted\': 1,\n+ "_authenticator": self._get_authenticator(),\n+ "users.id:records": self.normal_user,\n+ "users.roles:list:records": "Manager",\n+ "form.button.Modify": "Save",\n+ "form.submitted": 1,\n }\n post_data = urlencode(form)\n self.browser.post(self.usergroups_url, post_data)\n- self.assertIn(\'Status: 200\', str(self.browser.headers))\n+ self.assertIn("Status: 200", str(self.browser.headers))\n \n roles = self.portal.acl_users.getUserById(self.normal_user).getRoles()\n- self.assertEqual([\'Manager\', \'Authenticated\'], roles)\n+ self.assertEqual(["Manager", "Authenticated"], roles)\n \n def testNonManagersCannotDelegateManagerRoleForUsers(self):\n # a user without the Manager role cannot delegate the Manager role\n- self.browser.addHeader(\n- \'Authorization\', f\'Basic siteadmin:{TEST_USER_PASSWORD}\')\n+ self.browser.addHeader("Authorization", f"Basic siteadmin:{TEST_USER_PASSWORD}")\n self.browser.open(self.usergroups_url)\n form = {\n- \'_authenticator\': self._get_authenticator(),\n- \'users.id:records\': self.normal_user,\n- \'users.roles:list:records\': \'Manager\',\n- \'form.button.Modify\': \'Save\',\n- \'form.submitted\': 1,\n+ "_authenticator": self._get_authenticator(),\n+ "users.id:records": self.normal_user,\n+ "users.roles:list:records": "Manager",\n+ "form.button.Modify": "Save",\n+ "form.submitted": 1,\n }\n post_data = urlencode(form)\n with self.assertRaises(zExceptions.Forbidden):\n self.browser.post(self.usergroups_url, post_data)\n roles = self.portal.acl_users.getUserById(self.normal_user).getRoles()\n- self.assertEqual([\'Member\', \'Authenticated\'], roles)\n+ self.assertEqual(["Member", "Authenticated"], roles)\n \n def testNonManagersCanEditOtherRolesOfUsersWithManagerRole(self):\n- roles = self.portal.acl_users.getUserById(\'root\').getRoles()\n- self.assertEqual([\'Manager\', \'Authenticated\'], roles)\n- self.browser.addHeader(\n- \'Authorization\', f\'Basic siteadmin:{TEST_USER_PASSWORD}\')\n+ roles = self.portal.acl_users.getUserById("root").getRoles()\n+ self.assertEqual(["Manager", "Authenticated"], roles)\n+ self.browser.addHeader("Authorization", f"Basic siteadmin:{TEST_USER_PASSWORD}")\n self.browser.open(self.usergroups_url)\n form = {\n- \'_authenticator\': self._get_authenticator(),\n- \'users.id:records\': \'root\',\n- \'users.roles:list:records\': (\'Member\', \'Manager\'),\n- \'form.button.Modify\': \'Save\',\n- \'form.submitted\': 1,\n+ "_authenticator": self._get_authenticator(),\n+ "users.id:records": "root",\n+ "users.roles:list:records": ("Member", "Manager"),\n+ "form.button.Modify": "Save",\n+ "form.submitted": 1,\n }\n post_data = urlencode(form, doseq=True)\n self.browser.post(self.usergroups_url, post_data)\n- roles = self.portal.acl_users.getUserById(\'root\').getRoles()\n- self.assertEqual([\'Authenticated\', \'Manager\', \'Member\'], sorted(roles))\n+ roles = self.portal.acl_users.getUserById("root").getRoles()\n+ self.assertEqual(["Authenticated", "Manager", "Member"], sorted(roles))\n \n def testGroupManagerRoleCheckboxIsDisabledForNonManagers(self):\n- self.browser.addHeader(\n- \'Authorization\', f\'Basic siteadmin:{TEST_USER_PASSWORD}\')\n+ self.browser.addHeader("Authorization", f"Basic siteadmin:{TEST_USER_PASSWORD}")\n self.browser.open(self.groups_url)\n contents = self._simplify_white_space(self.browser.contents)\n- self.assertTrue(\' \' in contents)\n+ self.assertTrue(\n+ \' \' in contents\n+ )\n \n def testManagerCanDelegateManagerRoleForGroups(self):\n # a user with the Manager role can grant the Manager role\n- roles = self.portal.acl_users.getGroupById(\'Reviewers\').getRoles()\n- self.assertEqual([\'Reviewer\', \'Authenticated\'], roles)\n+ roles = self.portal.acl_users.getGroupById("Reviewers").getRoles()\n+ self.assertEqual(["Reviewer", "Authenticated"], roles)\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n self.browser.open(self.groups_url)\n form = {\n- \'_authenticator\': self._get_authenticator(),\n- \'group_Reviewers:list\': (\'\', \'Manager\'),\n- \'form.button.Modify\': \'Save\',\n- \'form.submitted\': 1,\n+ "_authenticator": self._get_authenticator(),\n+ "group_Reviewers:list": ("", "Manager"),\n+ "form.button.Modify": "Save",\n+ "form.submitted": 1,\n }\n post_data = urlencode(form, doseq=True)\n self.browser.post(self.groups_url, post_data)\n- roles = self.portal.acl_users.getGroupById(\'Reviewers\').getRoles()\n- self.assertEqual([\'Manager\', \'Authenticated\'], roles)\n+ roles = self.portal.acl_users.getGroupById("Reviewers").getRoles()\n+ self.assertEqual(["Manager", "Authenticated"], roles)\n \n def testNonManagersCannotDelegateManagerRoleForGroups(self):\n # a user without the Manager role cannot delegate the Manager role\n- self.browser.addHeader(\n- \'Authorization\', f\'Basic siteadmin:{TEST_USER_PASSWORD}\')\n+ self.browser.addHeader("Authorization", f"Basic siteadmin:{TEST_USER_PASSWORD}")\n \n self.browser.open(self.groups_url)\n form = {\n- \'_authenticator\': self._get_authenticator(),\n- \'group_Reviewers:list\': (\'\', \'Manager\'),\n- \'form.button.Modify\': \'Save\',\n- \'form.submitted\': 1,\n+ "_authenticator": self._get_authenticator(),\n+ "group_Reviewers:list": ("", "Manager"),\n+ "form.button.Modify": "Save",\n+ "form.submitted": 1,\n }\n post_data = urlencode(form, doseq=True)\n with self.assertRaises(zExceptions.Forbidden):\n self.browser.post(self.groups_url, post_data)\n # self.assertEqual(403, res.status)\n- roles = self.portal.acl_users.getGroupById(\'Reviewers\').getRoles()\n- self.assertEqual([\'Reviewer\', \'Authenticated\'], roles)\n+ roles = self.portal.acl_users.getGroupById("Reviewers").getRoles()\n+ self.assertEqual(["Reviewer", "Authenticated"], roles)\n \n def testNonManagersCanEditOtherRolesOfGroupsWithManagerRole(self):\n- self.browser.addHeader(\n- \'Authorization\', f\'Basic siteadmin:{TEST_USER_PASSWORD}\')\n+ self.browser.addHeader("Authorization", f"Basic siteadmin:{TEST_USER_PASSWORD}")\n \n- roles = self.portal.acl_users.getUserById(\'root\').getRoles()\n- self.assertEqual([\'Manager\', \'Authenticated\'], roles)\n+ roles = self.portal.acl_users.getUserById("root").getRoles()\n+ self.assertEqual(["Manager", "Authenticated"], roles)\n self.browser.open(self.groups_url)\n form = {\n- \'_authenticator\': self._get_authenticator(),\n- \'group_Administrators:list\': (\'\', \'Member\', \'Manager\'),\n- \'form.button.Modify\': \'Save\',\n- \'form.submitted\': 1,\n+ "_authenticator": self._get_authenticator(),\n+ "group_Administrators:list": ("", "Member", "Manager"),\n+ "form.button.Modify": "Save",\n+ "form.submitted": 1,\n }\n post_data = urlencode(form, doseq=True)\n self.browser.post(self.groups_url, post_data)\n # self.assertEqual(200, res.status)\n- roles = self.portal.acl_users.getGroupById(\'Administrators\').getRoles()\n- self.assertEqual([\'Authenticated\', \'Manager\', \'Member\'], sorted(roles))\n+ roles = self.portal.acl_users.getGroupById("Administrators").getRoles()\n+ self.assertEqual(["Authenticated", "Manager", "Member"], sorted(roles))\n \n def test_usergroup_usermembership_blocks_escalation(self):\n- self.browser.addHeader(\n- \'Authorization\', f\'Basic siteadmin:{TEST_USER_PASSWORD}\')\n+ self.browser.addHeader("Authorization", f"Basic siteadmin:{TEST_USER_PASSWORD}")\n \n # groups granting the Manager role shouldn\'t show as a valid option to\n # add\n self.browser.open(\n- self.portal_url + \'/@@usergroup-usermembership?userid=%s\' % self.normal_user)\n+ self.portal_url + "/@@usergroup-usermembership?userid=%s" % self.normal_user\n+ )\n contents = self._simplify_white_space(self.browser.contents)\n self.assertTrue(\n \' \'\n- in contents)\n+ in contents\n+ )\n \n form = {\n- \'_authenticator\': self._get_authenticator(),\n- \'users.id:records\': \'root\',\n- \'delete:list\': \'root\',\n- \'form.button.Modify\': \'Save\',\n- \'form.submitted\': 1,\n+ "_authenticator": self._get_authenticator(),\n+ "users.id:records": "root",\n+ "delete:list": "root",\n+ "form.button.Modify": "Save",\n+ "form.submitted": 1,\n }\n post_data = urlencode(form)\n with self.assertRaises(zExceptions.Forbidden):\n self.browser.post(self.usergroups_url, post_data)\n # self.assertEqual(403, res.status)\n- user = self.portal.acl_users.getUserById(\'root\')\n+ user = self.portal.acl_users.getUserById("root")\n self.assertTrue(user is not None)\n \n def test_groups_overview_blocks_deleting_managers(self):\n # a user without the Manager role cannot delete a group with the\n # Manager role\n- self.browser.addHeader(\n- \'Authorization\', f\'Basic siteadmin:{TEST_USER_PASSWORD}\')\n+ self.browser.addHeader("Authorization", f"Basic siteadmin:{TEST_USER_PASSWORD}")\n \n self.browser.open(self.groups_url)\n contents = self._simplify_white_space(self.browser.contents)\n@@ -335,14 +332,14 @@ def test_groups_overview_blocks_deleting_managers(self):\n )\n \n form = {\n- \'_authenticator\': self._get_authenticator(),\n- \'delete:list\': \'Administrators\',\n- \'form.button.Modify\': \'Save\',\n- \'form.submitted\': 1,\n+ "_authenticator": self._get_authenticator(),\n+ "delete:list": "Administrators",\n+ "form.button.Modify": "Save",\n+ "form.submitted": 1,\n }\n post_data = urlencode(form)\n with self.assertRaises(zExceptions.Forbidden):\n self.browser.post(self.groups_url, post_data)\n # self.assertEqual(403, res.status)\n- group = self.portal.acl_users.getGroupById(\'Administrators\')\n+ group = self.portal.acl_users.getGroupById("Administrators")\n self.assertTrue(group is not None)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_dateandtime.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_dateandtime.py\nindex 37c6e41dbd..487f430ff7 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_dateandtime.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_dateandtime.py\n@@ -7,41 +7,41 @@\n \n \n class DateAndTimeRegistryIntegrationTest(unittest.TestCase):\n- """Test date and time related settings.\n- """\n+ """Test date and time related settings."""\n \n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n \n def test_controlpanel_schema(self):\n- self.assertTrue(\'portal_timezone\' in IDateAndTimeSchema.names())\n- self.assertTrue(\'available_timezones\' in IDateAndTimeSchema.names())\n- self.assertTrue(\'first_weekday\' in IDateAndTimeSchema.names())\n+ self.assertTrue("portal_timezone" in IDateAndTimeSchema.names())\n+ self.assertTrue("available_timezones" in IDateAndTimeSchema.names())\n+ self.assertTrue("first_weekday" in IDateAndTimeSchema.names())\n \n def test_first_weekday(self):\n # Make sure the first weekday was set when the profile was run.\n- first_weekday = self.portal.portal_registry[\'plone.first_weekday\']\n+ first_weekday = self.portal.portal_registry["plone.first_weekday"]\n self.assertEqual(first_weekday, 6)\n \n # Change the site language. Re-running the import step should not\n # change the setting.\n portal = self.portal\n old_language = portal.language\n- portal.language = \'de\'\n+ portal.language = "de"\n from Products.CMFPlone.setuphandlers import first_weekday_setup\n+\n first_weekday_setup(portal)\n- first_weekday = self.portal.portal_registry[\'plone.first_weekday\']\n+ first_weekday = self.portal.portal_registry["plone.first_weekday"]\n self.assertEqual(first_weekday, 6)\n \n # But if we remove the setting, re-running the step should set it based\n # on the language.\n- self.portal.portal_registry[\'plone.first_weekday\'] = None\n+ self.portal.portal_registry["plone.first_weekday"] = None\n first_weekday_setup(portal)\n- first_weekday = self.portal.portal_registry[\'plone.first_weekday\']\n+ first_weekday = self.portal.portal_registry["plone.first_weekday"]\n self.assertEqual(first_weekday, 0)\n \n # Restore the site language.\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_doctest.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_doctest.py\nindex 764cb3781d..500a9ab81c 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_doctest.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_doctest.py\n@@ -9,23 +9,24 @@\n \n \n optionflags = (\n- doctest.ELLIPSIS |\n- doctest.NORMALIZE_WHITESPACE |\n- doctest.REPORT_ONLY_FIRST_FAILURE)\n+ doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_ONLY_FIRST_FAILURE\n+)\n normal_testfiles = [\n- \'../README.rst\',\n+ "../README.rst",\n ]\n \n \n def test_suite():\n suite = unittest.TestSuite()\n- suite.addTests([\n- layered(\n- doctest.DocFileSuite(\n- test,\n- optionflags=optionflags,\n- globs={\'pprint\': pprint.pprint}\n- ),\n- layer=PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n- ) for test in normal_testfiles])\n+ suite.addTests(\n+ [\n+ layered(\n+ doctest.DocFileSuite(\n+ test, optionflags=optionflags, globs={"pprint": pprint.pprint}\n+ ),\n+ layer=PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING,\n+ )\n+ for test in normal_testfiles\n+ ]\n+ )\n return suite\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_editing.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_editing.py\nindex 1d86e488b7..158d4f30ad 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_editing.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_editing.py\n@@ -16,32 +16,32 @@ class EditingRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- IEditingSchema, prefix="plone")\n+ self.settings = registry.forInterface(IEditingSchema, prefix="plone")\n \n def test_editing_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="editing-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="editing-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_editing_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'EditingSettings\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "EditingSettings"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_default_editor_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'default_editor\'))\n+ self.assertTrue(hasattr(self.settings, "default_editor"))\n \n def test_ext_editor_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'ext_editor\'))\n+ self.assertTrue(hasattr(self.settings, "ext_editor"))\n \n def test_enable_link_integrity_checks_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'enable_link_integrity_checks\'))\n+ self.assertTrue(hasattr(self.settings, "enable_link_integrity_checks"))\n \n def test_lock_on_ttw_edit_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'lock_on_ttw_edit\'))\n+ self.assertTrue(hasattr(self.settings, "lock_on_ttw_edit"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_events.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_events.py\nindex eba74102c5..e9275674c9 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_events.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_events.py\n@@ -9,36 +9,33 @@\n \n \n class SecurityControlPanelEventsTest(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n self.security_settings = getAdapter(self.portal, ISecuritySchema)\n \n def _create_user(self, user_id=None, email=None):\n """Helper function for creating a test user."""\n- registration = getToolByName(self.portal, \'portal_registration\', None)\n+ registration = getToolByName(self.portal, "portal_registration", None)\n registration.addMember(\n user_id,\n- \'password\',\n- [\'Member\'],\n- properties={\'email\': email, \'username\': user_id}\n+ "password",\n+ ["Member"],\n+ properties={"email": email, "username": user_id},\n )\n- membership = getToolByName(self.portal, \'portal_membership\', None)\n+ membership = getToolByName(self.portal, "portal_membership", None)\n return membership.getMemberById(user_id)\n \n def _is_self_reg_enabled(self):\n """Helper function to determine if self registration was properly\n enabled.\n """\n- app_perms = self.portal.rolesOfPermission(\n- permission=\'Add portal member\')\n+ app_perms = self.portal.rolesOfPermission(permission="Add portal member")\n for app_perm in app_perms:\n- if app_perm[\'name\'] == \'Anonymous\' \\\n- and app_perm[\'selected\'] == \'SELECTED\':\n+ if app_perm["name"] == "Anonymous" and app_perm["selected"] == "SELECTED":\n return True\n return False\n \n@@ -62,22 +59,22 @@ def test_handle_enable_user_folders_condition_check(self):\n """Check that this event handler is not run for other ISecuritySchema\n records.\n """\n- portal_actions = getToolByName(self.portal, \'portal_actions\', None)\n- self.assertFalse(\'mystuff\' in portal_actions[\'user\'].keys())\n+ portal_actions = getToolByName(self.portal, "portal_actions", None)\n+ self.assertFalse("mystuff" in portal_actions["user"].keys())\n self.security_settings.use_uuid_as_userid = True\n- self.assertFalse(\'mystuff\' in portal_actions[\'user\'].keys())\n+ self.assertFalse("mystuff" in portal_actions["user"].keys())\n \n def test_handle_enable_user_folders_enabled_no_mystuff_yet(self):\n- portal_actions = getToolByName(self.portal, \'portal_actions\', None)\n+ portal_actions = getToolByName(self.portal, "portal_actions", None)\n \n # if we enable the setting, mystuff action should be added\n- self.assertFalse(\'mystuff\' in portal_actions[\'user\'].keys())\n+ self.assertFalse("mystuff" in portal_actions["user"].keys())\n self.security_settings.enable_user_folders = True\n- self.assertTrue(\'mystuff\' in portal_actions[\'user\'].keys())\n- self.assertTrue(portal_actions[\'user\'][\'mystuff\'].visible)\n+ self.assertTrue("mystuff" in portal_actions["user"].keys())\n+ self.assertTrue(portal_actions["user"]["mystuff"].visible)\n \n def test_handle_enable_user_folders_enabled_has_mystuff(self):\n- portal_actions = getToolByName(self.portal, \'portal_actions\', None)\n+ portal_actions = getToolByName(self.portal, "portal_actions", None)\n \n # if we enable the setting, disable it, then enable it again,\n # the mystuff action should still be there and visible\n@@ -85,56 +82,56 @@ def test_handle_enable_user_folders_enabled_has_mystuff(self):\n self.security_settings.enable_user_folders = False\n self.security_settings.enable_user_folders = True\n \n- self.assertTrue(\'mystuff\' in portal_actions[\'user\'].keys())\n- self.assertTrue(portal_actions[\'user\'][\'mystuff\'].visible)\n+ self.assertTrue("mystuff" in portal_actions["user"].keys())\n+ self.assertTrue(portal_actions["user"]["mystuff"].visible)\n \n def test_handle_enable_user_folders_disabled_no_mystuff_yet(self):\n- portal_actions = getToolByName(self.portal, \'portal_actions\', None)\n+ portal_actions = getToolByName(self.portal, "portal_actions", None)\n \n # if the mystuff action is not there yet, this should have no effect\n self.security_settings.enable_user_folders = False\n- self.assertFalse(\'mystuff\' in portal_actions[\'user\'].keys())\n+ self.assertFalse("mystuff" in portal_actions["user"].keys())\n \n def test_handle_enable_user_folders_disabled_has_mystuff(self):\n- portal_actions = getToolByName(self.portal, \'portal_actions\', None)\n+ portal_actions = getToolByName(self.portal, "portal_actions", None)\n \n # if the setting was enabled and then disabled, the mystuff action\n # should be hidden\n self.security_settings.enable_user_folders = True\n self.security_settings.enable_user_folders = False\n- self.assertTrue(\'mystuff\' in portal_actions[\'user\'].keys())\n- self.assertFalse(portal_actions[\'user\'][\'mystuff\'].visible)\n+ self.assertTrue("mystuff" in portal_actions["user"].keys())\n+ self.assertFalse(portal_actions["user"]["mystuff"].visible)\n \n def test_handle_use_email_as_login_condition_check(self):\n """Check that this event handler is not run for other ISecuritySchema\n records.\n """\n- self._create_user(user_id=\'joe\', email=\'joe@test.com\')\n- pas = getToolByName(self.portal, \'acl_users\')\n+ self._create_user(user_id="joe", email="joe@test.com")\n+ pas = getToolByName(self.portal, "acl_users")\n \n- self.assertEqual(len(pas.searchUsers(name=\'joe@test.com\')), 0)\n+ self.assertEqual(len(pas.searchUsers(name="joe@test.com")), 0)\n self.security_settings.use_uuid_as_userid = True\n- self.assertEqual(len(pas.searchUsers(name=\'joe@test.com\')), 0)\n+ self.assertEqual(len(pas.searchUsers(name="joe@test.com")), 0)\n \n def test_handle_use_email_as_login_enabled(self):\n- self._create_user(user_id=\'joe\', email=\'joe@test.com\')\n- pas = getToolByName(self.portal, \'acl_users\')\n+ self._create_user(user_id="joe", email="joe@test.com")\n+ pas = getToolByName(self.portal, "acl_users")\n \n- self.assertEqual(len(pas.searchUsers(name=\'joe@test.com\')), 0)\n- self.assertEqual(len(pas.searchUsers(name=\'joe\')), 1)\n+ self.assertEqual(len(pas.searchUsers(name="joe@test.com")), 0)\n+ self.assertEqual(len(pas.searchUsers(name="joe")), 1)\n \n # if we enable use_email_as_login, login name should be migrated\n # to email\n self.security_settings.use_email_as_login = True\n- self.assertEqual(len(pas.searchUsers(name=\'joe@test.com\')), 1)\n+ self.assertEqual(len(pas.searchUsers(name="joe@test.com")), 1)\n \n def test_handle_use_email_as_login_disabled(self):\n- self._create_user(user_id=\'joe\', email=\'joe@test.com\')\n- pas = getToolByName(self.portal, \'acl_users\')\n+ self._create_user(user_id="joe", email="joe@test.com")\n+ pas = getToolByName(self.portal, "acl_users")\n \n # if we enable use_email_as_login, then disabled it, the login name\n # should be migrated back to user id\n self.security_settings.use_email_as_login = True\n self.security_settings.use_email_as_login = False\n- self.assertEqual(len(pas.searchUsers(name=\'joe@test.com\')), 0)\n- self.assertEqual(len(pas.searchUsers(name=\'joe\')), 1)\n+ self.assertEqual(len(pas.searchUsers(name="joe@test.com")), 0)\n+ self.assertEqual(len(pas.searchUsers(name="joe")), 1)\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_filter.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_filter.py\nindex 1970bb4cf7..ee817eb16e 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_filter.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_filter.py\n@@ -16,32 +16,32 @@ class FilterRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self): # NOQA\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- IFilterSchema, prefix="plone")\n+ self.settings = registry.forInterface(IFilterSchema, prefix="plone")\n \n def test_filter_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="filter-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="filter-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_filter_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'FilterSettings\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "FilterSettings"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_disable_filtering_setting(self):\n- self.assertTrue(hasattr(self.settings, \'disable_filtering\'))\n+ self.assertTrue(hasattr(self.settings, "disable_filtering"))\n \n def test_nasty_tags_setting(self):\n- self.assertTrue(hasattr(self.settings, \'nasty_tags\'))\n+ self.assertTrue(hasattr(self.settings, "nasty_tags"))\n \n def test_valid_tags_setting(self):\n- self.assertTrue(hasattr(self.settings, \'valid_tags\'))\n+ self.assertTrue(hasattr(self.settings, "valid_tags"))\n \n def test_custom_attributes_setting(self):\n- self.assertTrue(hasattr(self.settings, \'custom_attributes\'))\n+ self.assertTrue(hasattr(self.settings, "custom_attributes"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_installer.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_installer.py\nindex b2d95e779a..7377004f56 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_installer.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_installer.py\n@@ -15,26 +15,27 @@ class AddonsIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n self.installer = get_installer(self.portal, self.request)\n \n def test_addons_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="prefs_install_products_form")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="prefs_install_products_form"\n+ )\n self.assertTrue(view())\n \n def test_addons_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertIn(\'QuickInstaller\', [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertIn(\n+ "QuickInstaller",\n+ [a.getAction(self)["id"] for a in self.controlpanel.listActions()],\n+ )\n \n def test_installer_view(self):\n from Products.CMFPlone.controlpanel.browser.quickinstaller import InstallerView\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="installer")\n+\n+ view = getMultiAdapter((self.portal, self.portal.REQUEST), name="installer")\n self.assertTrue(isinstance(view, InstallerView))\n self.assertTrue(isinstance(self.installer, InstallerView))\n \n@@ -55,29 +56,32 @@ def _test_install_uninstall(self, product):\n def test_install_uninstall_cmfplacefulworkflow_without_products(self):\n try:\n import Products.CMFPlacefulWorkflow\n+\n Products.CMFPlacefulWorkflow # pyflakes\n except ImportError:\n return\n- self._test_install_uninstall(\'CMFPlacefulWorkflow\')\n+ self._test_install_uninstall("CMFPlacefulWorkflow")\n \n def test_install_uninstall_cmfplacefulworkflow_with_products(self):\n try:\n import Products.CMFPlacefulWorkflow\n+\n Products.CMFPlacefulWorkflow # pyflakes\n except ImportError:\n return\n- self._test_install_uninstall(\'Products.CMFPlacefulWorkflow\')\n+ self._test_install_uninstall("Products.CMFPlacefulWorkflow")\n \n def test_install_uninstall_package(self):\n try:\n import plone.session\n+\n plone.session # pyflakes\n except ImportError:\n return\n- self._test_install_uninstall(\'plone.session\')\n+ self._test_install_uninstall("plone.session")\n \n def test_unknown_package(self):\n- product = \'no.product\'\n+ product = "no.product"\n self.assertFalse(self.installer.is_product_installable(product))\n self.assertFalse(self.installer.is_product_installed(product))\n # Install the product.\n@@ -92,293 +96,294 @@ def test_unknown_package(self):\n def test_plone_app_upgrade_not_installable(self):\n installable = self.installer.is_product_installable\n # Test a few current and future plone.app.upgrade versions.\n- self.assertFalse(installable(\'plone.app.upgrade\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v30\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v40\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v50\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v51\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v52\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v53\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v60\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v61\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v62\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v63\'))\n- self.assertFalse(installable(\'plone.app.upgrade.v70\'))\n+ self.assertFalse(installable("plone.app.upgrade"))\n+ self.assertFalse(installable("plone.app.upgrade.v30"))\n+ self.assertFalse(installable("plone.app.upgrade.v40"))\n+ self.assertFalse(installable("plone.app.upgrade.v50"))\n+ self.assertFalse(installable("plone.app.upgrade.v51"))\n+ self.assertFalse(installable("plone.app.upgrade.v52"))\n+ self.assertFalse(installable("plone.app.upgrade.v53"))\n+ self.assertFalse(installable("plone.app.upgrade.v60"))\n+ self.assertFalse(installable("plone.app.upgrade.v61"))\n+ self.assertFalse(installable("plone.app.upgrade.v62"))\n+ self.assertFalse(installable("plone.app.upgrade.v63"))\n+ self.assertFalse(installable("plone.app.upgrade.v70"))\n \n def test_latest_upgrade_profiles3(self):\n xmlconfig.file(\n- \'test_upgrades1.zcml\',\n+ "test_upgrades1.zcml",\n package=tests,\n- context=self.layer[\'configurationContext\']\n+ context=self.layer["configurationContext"],\n )\n latest = self.installer.get_latest_upgrade_step(\n- \'Products.CMFPlone:testfixture1\')\n- self.assertEqual(latest, \'3\')\n+ "Products.CMFPlone:testfixture1"\n+ )\n+ self.assertEqual(latest, "3")\n \n def test_latest_upgrade_profiles2(self):\n # make sure strings don\'t break things\n # note that pkg_resources interprets 1 as\n # \'\'00000001\', which is > \'banana\'\n xmlconfig.file(\n- \'test_upgrades2.zcml\',\n+ "test_upgrades2.zcml",\n package=tests,\n- context=self.layer[\'configurationContext\']\n+ context=self.layer["configurationContext"],\n )\n latest = self.installer.get_latest_upgrade_step(\n- \'Products.CMFPlone:testfixture2\')\n- self.assertEqual(latest, \'3\')\n+ "Products.CMFPlone:testfixture2"\n+ )\n+ self.assertEqual(latest, "3")\n \n def test_latest_upgrade_profiles_unknown(self):\n- latest = self.installer.get_latest_upgrade_step(\'no.profile\')\n+ latest = self.installer.get_latest_upgrade_step("no.profile")\n self.assertEqual(latest, UNKNOWN)\n \n def test_is_profile_installed(self):\n- self.assertFalse(self.installer.is_profile_installed(\'foo:default\'))\n- self.assertTrue(self.installer.is_profile_installed(\n- \'plone.app.dexterity:default\'))\n- self.assertTrue(self.installer.is_profile_installed(\n- \'profile-plone.app.dexterity:default\'))\n+ self.assertFalse(self.installer.is_profile_installed("foo:default"))\n+ self.assertTrue(\n+ self.installer.is_profile_installed("plone.app.dexterity:default")\n+ )\n+ self.assertTrue(\n+ self.installer.is_profile_installed("profile-plone.app.dexterity:default")\n+ )\n \n def test_is_product_installed(self):\n- self.assertFalse(self.installer.is_product_installed(\'foo\'))\n- self.assertFalse(self.installer.is_product_installed(\'plone.session\'))\n- self.assertTrue(self.installer.is_product_installed(\n- \'plone.app.dexterity\'))\n+ self.assertFalse(self.installer.is_product_installed("foo"))\n+ self.assertFalse(self.installer.is_product_installed("plone.session"))\n+ self.assertTrue(self.installer.is_product_installed("plone.app.dexterity"))\n \n def test_get_install_profiles(self):\n # Note: this method name is a bit of a misnomer.\n # It lists *all* extension profiles.\n # The method seems unneeded.\n- self.assertEqual(self.installer.get_install_profiles(\'foo\'), [])\n- session_profiles = self.installer.get_install_profiles(\'plone.session\')\n- self.assertIn(\'plone.session:default\', session_profiles)\n- self.assertIn(\'plone.session:uninstall\', session_profiles)\n+ self.assertEqual(self.installer.get_install_profiles("foo"), [])\n+ session_profiles = self.installer.get_install_profiles("plone.session")\n+ self.assertIn("plone.session:default", session_profiles)\n+ self.assertIn("plone.session:uninstall", session_profiles)\n self.assertEqual(\n- self.installer.get_install_profiles(\'plone.app.dexterity\'),\n- [\'plone.app.dexterity:default\', \'plone.app.dexterity:testing\'])\n+ self.installer.get_install_profiles("plone.app.dexterity"),\n+ ["plone.app.dexterity:default", "plone.app.dexterity:testing"],\n+ )\n try:\n import Products.CMFPlacefulWorkflow\n+\n Products.CMFPlacefulWorkflow # pyflakes\n except ImportError:\n return\n self.assertEqual(\n- self.installer.get_install_profiles(\'CMFPlacefulWorkflow\'),\n- [\'Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow\',\n- \'Products.CMFPlacefulWorkflow:base\',\n- \'Products.CMFPlacefulWorkflow:uninstall\'])\n+ self.installer.get_install_profiles("CMFPlacefulWorkflow"),\n+ [\n+ "Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow",\n+ "Products.CMFPlacefulWorkflow:base",\n+ "Products.CMFPlacefulWorkflow:uninstall",\n+ ],\n+ )\n self.assertEqual(\n- self.installer.get_install_profiles(\n- \'Products.CMFPlacefulWorkflow\'),\n- [\'Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow\',\n- \'Products.CMFPlacefulWorkflow:base\',\n- \'Products.CMFPlacefulWorkflow:uninstall\'])\n+ self.installer.get_install_profiles("Products.CMFPlacefulWorkflow"),\n+ [\n+ "Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow",\n+ "Products.CMFPlacefulWorkflow:base",\n+ "Products.CMFPlacefulWorkflow:uninstall",\n+ ],\n+ )\n \n def test_get_install_profile(self):\n- self.assertIsNone(self.installer.get_install_profile(\'foo\'))\n- profile = self.installer.get_install_profile(\'plone.session\')\n- self.assertEqual(profile[\'id\'], \'plone.session:default\')\n- profile = self.installer.get_install_profile(\'plone.app.dexterity\')\n- self.assertEqual(profile[\'id\'], \'plone.app.dexterity:default\')\n+ self.assertIsNone(self.installer.get_install_profile("foo"))\n+ profile = self.installer.get_install_profile("plone.session")\n+ self.assertEqual(profile["id"], "plone.session:default")\n+ profile = self.installer.get_install_profile("plone.app.dexterity")\n+ self.assertEqual(profile["id"], "plone.app.dexterity:default")\n try:\n import Products.CMFPlacefulWorkflow\n+\n Products.CMFPlacefulWorkflow # pyflakes\n except ImportError:\n return\n- profile = self.installer.get_install_profile(\'CMFPlacefulWorkflow\')\n+ profile = self.installer.get_install_profile("CMFPlacefulWorkflow")\n self.assertEqual(\n- profile[\'id\'], \'Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow\')\n- profile = self.installer.get_install_profile(\n- \'Products.CMFPlacefulWorkflow\')\n+ profile["id"], "Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow"\n+ )\n+ profile = self.installer.get_install_profile("Products.CMFPlacefulWorkflow")\n self.assertEqual(\n- profile[\'id\'], \'Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow\')\n+ profile["id"], "Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow"\n+ )\n \n def test_get_uninstall_profile(self):\n- self.assertIsNone(self.installer.get_uninstall_profile(\'foo\'))\n- profile = self.installer.get_uninstall_profile(\'plone.session\')\n- self.assertEqual(profile[\'id\'], \'plone.session:uninstall\')\n- profile = self.installer.get_uninstall_profile(\'plone.app.dexterity\')\n+ self.assertIsNone(self.installer.get_uninstall_profile("foo"))\n+ profile = self.installer.get_uninstall_profile("plone.session")\n+ self.assertEqual(profile["id"], "plone.session:uninstall")\n+ profile = self.installer.get_uninstall_profile("plone.app.dexterity")\n self.assertIsNone(profile)\n try:\n import Products.CMFPlacefulWorkflow\n+\n Products.CMFPlacefulWorkflow # pyflakes\n except ImportError:\n return\n- profile = self.installer.get_uninstall_profile(\'CMFPlacefulWorkflow\')\n- self.assertEqual(\n- profile[\'id\'], \'Products.CMFPlacefulWorkflow:uninstall\')\n- profile = self.installer.get_uninstall_profile(\n- \'Products.CMFPlacefulWorkflow\')\n- self.assertEqual(\n- profile[\'id\'], \'Products.CMFPlacefulWorkflow:uninstall\')\n+ profile = self.installer.get_uninstall_profile("CMFPlacefulWorkflow")\n+ self.assertEqual(profile["id"], "Products.CMFPlacefulWorkflow:uninstall")\n+ profile = self.installer.get_uninstall_profile("Products.CMFPlacefulWorkflow")\n+ self.assertEqual(profile["id"], "Products.CMFPlacefulWorkflow:uninstall")\n \n def test_get_product_version(self):\n- self.assertFalse(self.installer.get_product_version(\'foo\'))\n- version = self.installer.get_product_version(\'plone.session\')\n- self.assertIn(\'.\', version)\n- version = self.installer.get_product_version(\'plone.app.dexterity\')\n- self.assertIn(\'.\', version)\n+ self.assertFalse(self.installer.get_product_version("foo"))\n+ version = self.installer.get_product_version("plone.session")\n+ self.assertIn(".", version)\n+ version = self.installer.get_product_version("plone.app.dexterity")\n+ self.assertIn(".", version)\n try:\n import Products.CMFPlacefulWorkflow\n+\n Products.CMFPlacefulWorkflow # pyflakes\n except ImportError:\n return\n- version = self.installer.get_product_version(\'CMFPlacefulWorkflow\')\n- self.assertIn(\'.\', version)\n- version = self.installer.get_product_version(\n- \'Products.CMFPlacefulWorkflow\')\n- self.assertIn(\'.\', version)\n+ version = self.installer.get_product_version("CMFPlacefulWorkflow")\n+ self.assertIn(".", version)\n+ version = self.installer.get_product_version("Products.CMFPlacefulWorkflow")\n+ self.assertIn(".", version)\n \n def test_upgrade_info(self):\n # an unknown product\n- self.assertEqual(self.installer.upgrade_info(\'foo\'), {})\n+ self.assertEqual(self.installer.upgrade_info("foo"), {})\n # a not yet/ uninstalled product\n- info = self.installer.upgrade_info(\'plone.session\')\n- self.assertEqual(self.installer.upgrade_info(\'plone.session\'), {})\n+ info = self.installer.upgrade_info("plone.session")\n+ self.assertEqual(self.installer.upgrade_info("plone.session"), {})\n # an installed product\n- info = self.installer.upgrade_info(\'plone.app.dexterity\')\n- self.assertFalse(info[\'available\'])\n- self.assertFalse(info[\'required\'])\n- self.assertNotEqual(info[\'installedVersion\'], UNKNOWN)\n- self.assertEqual(info[\'installedVersion\'], info[\'newVersion\'])\n+ info = self.installer.upgrade_info("plone.app.dexterity")\n+ self.assertFalse(info["available"])\n+ self.assertFalse(info["required"])\n+ self.assertNotEqual(info["installedVersion"], UNKNOWN)\n+ self.assertEqual(info["installedVersion"], info["newVersion"])\n # fake an earlier version\n ps = self.portal.portal_setup\n- ps.setLastVersionForProfile(\'plone.app.dexterity:default\', \'2002\')\n- info = self.installer.upgrade_info(\'plone.app.dexterity\')\n- self.assertTrue(info[\'available\'])\n- self.assertTrue(info[\'required\'])\n- self.assertEqual(info[\'installedVersion\'], \'2002\')\n+ ps.setLastVersionForProfile("plone.app.dexterity:default", "2002")\n+ info = self.installer.upgrade_info("plone.app.dexterity")\n+ self.assertTrue(info["available"])\n+ self.assertTrue(info["required"])\n+ self.assertEqual(info["installedVersion"], "2002")\n # upgrade the product\n- self.assertTrue(self.installer.upgrade_product(\'plone.app.dexterity\'))\n- info = self.installer.upgrade_info(\'plone.app.dexterity\')\n- self.assertFalse(info[\'available\'])\n- self.assertFalse(info[\'required\'])\n- self.assertNotEqual(info[\'installedVersion\'], UNKNOWN)\n- self.assertEqual(info[\'installedVersion\'], info[\'newVersion\'])\n+ self.assertTrue(self.installer.upgrade_product("plone.app.dexterity"))\n+ info = self.installer.upgrade_info("plone.app.dexterity")\n+ self.assertFalse(info["available"])\n+ self.assertFalse(info["required"])\n+ self.assertNotEqual(info["installedVersion"], UNKNOWN)\n+ self.assertEqual(info["installedVersion"], info["newVersion"])\n \n def test_upgrade_product(self):\n # an unknown product\n- self.assertFalse(self.installer.upgrade_product(\'foo\'))\n+ self.assertFalse(self.installer.upgrade_product("foo"))\n \n # We do not complain about a not-yet/ uninstalled product.\n- self.assertTrue(self.installer.upgrade_product(\'plone.session\'))\n- info = self.installer.upgrade_info(\'plone.session\')\n+ self.assertTrue(self.installer.upgrade_product("plone.session"))\n+ info = self.installer.upgrade_info("plone.session")\n self.assertEqual(info, {})\n \n # We do not complain about an up to date product.\n- self.assertTrue(self.installer.upgrade_product(\'plone.app.dexterity\'))\n- info = self.installer.upgrade_info(\'plone.app.dexterity\')\n- self.assertNotEqual(info[\'installedVersion\'], UNKNOWN)\n- self.assertEqual(info[\'installedVersion\'], info[\'newVersion\'])\n+ self.assertTrue(self.installer.upgrade_product("plone.app.dexterity"))\n+ info = self.installer.upgrade_info("plone.app.dexterity")\n+ self.assertNotEqual(info["installedVersion"], UNKNOWN)\n+ self.assertEqual(info["installedVersion"], info["newVersion"])\n # fake an earlier version\n ps = self.portal.portal_setup\n- ps.setLastVersionForProfile(\'plone.app.dexterity:default\', \'2002\')\n- info = self.installer.upgrade_info(\'plone.app.dexterity\')\n- self.assertEqual(info[\'installedVersion\'], \'2002\')\n+ ps.setLastVersionForProfile("plone.app.dexterity:default", "2002")\n+ info = self.installer.upgrade_info("plone.app.dexterity")\n+ self.assertEqual(info["installedVersion"], "2002")\n # upgrade the product\n- self.assertTrue(self.installer.upgrade_product(\'plone.app.dexterity\'))\n- info = self.installer.upgrade_info(\'plone.app.dexterity\')\n- self.assertEqual(info[\'installedVersion\'], info[\'newVersion\'])\n+ self.assertTrue(self.installer.upgrade_product("plone.app.dexterity"))\n+ info = self.installer.upgrade_info("plone.app.dexterity")\n+ self.assertEqual(info["installedVersion"], info["newVersion"])\n \n # Try a Product too (not yet installed).\n- info = self.installer.upgrade_info(\'Products.CMFPlacefulWorkflow\')\n+ info = self.installer.upgrade_info("Products.CMFPlacefulWorkflow")\n self.assertEqual(info, {})\n- self.assertTrue(self.installer.upgrade_product(\n- \'Products.CMFPlacefulWorkflow\')\n- )\n- info = self.installer.upgrade_info(\'Products.CMFPlacefulWorkflow\')\n+ self.assertTrue(self.installer.upgrade_product("Products.CMFPlacefulWorkflow"))\n+ info = self.installer.upgrade_info("Products.CMFPlacefulWorkflow")\n self.assertEqual(info, {})\n- info = self.installer.upgrade_info(\'CMFPlacefulWorkflow\')\n+ info = self.installer.upgrade_info("CMFPlacefulWorkflow")\n self.assertEqual(info, {})\n- self.assertTrue(self.installer.upgrade_product(\'CMFPlacefulWorkflow\'))\n- info = self.installer.upgrade_info(\'CMFPlacefulWorkflow\')\n+ self.assertTrue(self.installer.upgrade_product("CMFPlacefulWorkflow"))\n+ info = self.installer.upgrade_info("CMFPlacefulWorkflow")\n self.assertEqual(info, {})\n # fake a version\n ps = self.portal.portal_setup\n ps.setLastVersionForProfile(\n- \'Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow\', \'0.0\')\n- info = self.installer.upgrade_info(\'Products.CMFPlacefulWorkflow\')\n- self.assertEqual(info[\'installedVersion\'], \'0.0\')\n- info = self.installer.upgrade_info(\'CMFPlacefulWorkflow\')\n- self.assertEqual(info[\'installedVersion\'], \'0.0\')\n+ "Products.CMFPlacefulWorkflow:CMFPlacefulWorkflow", "0.0"\n+ )\n+ info = self.installer.upgrade_info("Products.CMFPlacefulWorkflow")\n+ self.assertEqual(info["installedVersion"], "0.0")\n+ info = self.installer.upgrade_info("CMFPlacefulWorkflow")\n+ self.assertEqual(info["installedVersion"], "0.0")\n # upgrade the product\n- self.assertTrue(self.installer.upgrade_product(\'CMFPlacefulWorkflow\'))\n- info = self.installer.upgrade_info(\'CMFPlacefulWorkflow\')\n- self.assertEqual(info[\'installedVersion\'], info[\'newVersion\'])\n- info = self.installer.upgrade_info(\'Products.CMFPlacefulWorkflow\')\n- self.assertEqual(info[\'installedVersion\'], info[\'newVersion\'])\n+ self.assertTrue(self.installer.upgrade_product("CMFPlacefulWorkflow"))\n+ info = self.installer.upgrade_info("CMFPlacefulWorkflow")\n+ self.assertEqual(info["installedVersion"], info["newVersion"])\n+ info = self.installer.upgrade_info("Products.CMFPlacefulWorkflow")\n+ self.assertEqual(info["installedVersion"], info["newVersion"])\n \n def test_install_product(self):\n # an unknown product\n- self.assertFalse(self.installer.install_product(\'foo\'))\n+ self.assertFalse(self.installer.install_product("foo"))\n \n # an uninstalled product\n- self.assertFalse(self.installer.is_product_installed(\'plone.session\'))\n- self.assertTrue(self.installer.install_product(\'plone.session\'))\n- self.assertTrue(self.installer.is_product_installed(\'plone.session\'))\n+ self.assertFalse(self.installer.is_product_installed("plone.session"))\n+ self.assertTrue(self.installer.install_product("plone.session"))\n+ self.assertTrue(self.installer.is_product_installed("plone.session"))\n \n # We complain a bit when installing an already installed product.\n- self.assertTrue(\n- self.installer.is_product_installed(\'plone.app.dexterity\'))\n- self.assertFalse(self.installer.install_product(\'plone.app.dexterity\'))\n- self.assertTrue(\n- self.installer.is_product_installed(\'plone.app.dexterity\'))\n+ self.assertTrue(self.installer.is_product_installed("plone.app.dexterity"))\n+ self.assertFalse(self.installer.install_product("plone.app.dexterity"))\n+ self.assertTrue(self.installer.is_product_installed("plone.app.dexterity"))\n \n # Try a Product too.\n- self.assertFalse(\n- self.installer.is_product_installed(\'CMFPlacefulWorkflow\'))\n- self.assertTrue(self.installer.install_product(\'CMFPlacefulWorkflow\'))\n- self.assertTrue(self.installer.is_product_installed(\n- \'CMFPlacefulWorkflow\'))\n- self.assertTrue(self.installer.is_product_installed(\n- \'Products.CMFPlacefulWorkflow\'))\n+ self.assertFalse(self.installer.is_product_installed("CMFPlacefulWorkflow"))\n+ self.assertTrue(self.installer.install_product("CMFPlacefulWorkflow"))\n+ self.assertTrue(self.installer.is_product_installed("CMFPlacefulWorkflow"))\n+ self.assertTrue(\n+ self.installer.is_product_installed("Products.CMFPlacefulWorkflow")\n+ )\n # undo\n- self.assertTrue(self.installer.uninstall_product(\n- \'CMFPlacefulWorkflow\'))\n- self.assertFalse(self.installer.is_product_installed(\n- \'Products.CMFPlacefulWorkflow\'))\n+ self.assertTrue(self.installer.uninstall_product("CMFPlacefulWorkflow"))\n+ self.assertFalse(\n+ self.installer.is_product_installed("Products.CMFPlacefulWorkflow")\n+ )\n # redo with \'Products.\'\n- self.assertTrue(self.installer.install_product(\n- \'Products.CMFPlacefulWorkflow\'))\n- self.assertTrue(self.installer.is_product_installed(\n- \'CMFPlacefulWorkflow\'))\n- self.assertTrue(self.installer.is_product_installed(\n- \'Products.CMFPlacefulWorkflow\'))\n+ self.assertTrue(self.installer.install_product("Products.CMFPlacefulWorkflow"))\n+ self.assertTrue(self.installer.is_product_installed("CMFPlacefulWorkflow"))\n+ self.assertTrue(\n+ self.installer.is_product_installed("Products.CMFPlacefulWorkflow")\n+ )\n \n def test_uninstall_product(self):\n # an unknown product\n- self.assertFalse(self.installer.uninstall_product(\'foo\'))\n+ self.assertFalse(self.installer.uninstall_product("foo"))\n \n # We do not complain about an already uninstalled product.\n- self.assertFalse(self.installer.is_product_installed(\'plone.session\'))\n- self.assertTrue(self.installer.uninstall_product(\'plone.session\'))\n- self.assertFalse(self.installer.is_product_installed(\'plone.session\'))\n+ self.assertFalse(self.installer.is_product_installed("plone.session"))\n+ self.assertTrue(self.installer.uninstall_product("plone.session"))\n+ self.assertFalse(self.installer.is_product_installed("plone.session"))\n \n # We do complain about an installed product without uninstall profile.\n # Dexterity cannot be uninstalled.\n- self.assertTrue(\n- self.installer.is_product_installed(\'plone.app.dexterity\'))\n- self.assertFalse(self.installer.uninstall_product(\n- \'plone.app.dexterity\'))\n- self.assertTrue(\n- self.installer.is_product_installed(\'plone.app.dexterity\'))\n+ self.assertTrue(self.installer.is_product_installed("plone.app.dexterity"))\n+ self.assertFalse(self.installer.uninstall_product("plone.app.dexterity"))\n+ self.assertTrue(self.installer.is_product_installed("plone.app.dexterity"))\n \n # Try a Product too.\n- self.assertTrue(self.installer.install_product(\'CMFPlacefulWorkflow\'))\n- self.assertTrue(self.installer.uninstall_product(\n- \'CMFPlacefulWorkflow\'))\n- self.assertFalse(self.installer.is_product_installed(\n- \'CMFPlacefulWorkflow\'))\n- self.assertFalse(self.installer.is_product_installed(\n- \'Products.CMFPlacefulWorkflow\'))\n+ self.assertTrue(self.installer.install_product("CMFPlacefulWorkflow"))\n+ self.assertTrue(self.installer.uninstall_product("CMFPlacefulWorkflow"))\n+ self.assertFalse(self.installer.is_product_installed("CMFPlacefulWorkflow"))\n+ self.assertFalse(\n+ self.installer.is_product_installed("Products.CMFPlacefulWorkflow")\n+ )\n # Again with \'Products.\'\n- self.assertTrue(self.installer.install_product(\n- \'Products.CMFPlacefulWorkflow\'))\n- self.assertTrue(self.installer.uninstall_product(\n- \'Products.CMFPlacefulWorkflow\'))\n- self.assertFalse(self.installer.is_product_installed(\n- \'CMFPlacefulWorkflow\'))\n- self.assertFalse(self.installer.is_product_installed(\n- \'Products.CMFPlacefulWorkflow\'))\n+ self.assertTrue(self.installer.install_product("Products.CMFPlacefulWorkflow"))\n+ self.assertTrue(\n+ self.installer.uninstall_product("Products.CMFPlacefulWorkflow")\n+ )\n+ self.assertFalse(self.installer.is_product_installed("CMFPlacefulWorkflow"))\n+ self.assertFalse(\n+ self.installer.is_product_installed("Products.CMFPlacefulWorkflow")\n+ )\n \n \n def dummy_handler():\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_language.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_language.py\nindex 41e509718c..854b077f35 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_language.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_language.py\n@@ -16,56 +16,56 @@ class LanguageRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ILanguageSchema, prefix="plone")\n+ self.settings = registry.forInterface(ILanguageSchema, prefix="plone")\n \n def test_language_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="language-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="language-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_language_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'LanguageSettings\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "LanguageSettings"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_default_language_exists(self):\n- self.assertTrue(hasattr(self.settings, \'default_language\'))\n+ self.assertTrue(hasattr(self.settings, "default_language"))\n \n def test_available_languages_exists(self):\n- self.assertTrue(hasattr(self.settings, \'available_languages\'))\n+ self.assertTrue(hasattr(self.settings, "available_languages"))\n \n def test_use_combined_language_codes_exists(self):\n- self.assertTrue(hasattr(self.settings, \'use_combined_language_codes\'))\n+ self.assertTrue(hasattr(self.settings, "use_combined_language_codes"))\n \n def test_display_flags_exists(self):\n- self.assertTrue(hasattr(self.settings, \'display_flags\'))\n+ self.assertTrue(hasattr(self.settings, "display_flags"))\n \n def test_use_content_negotiation_exists(self):\n- self.assertTrue(hasattr(self.settings, \'use_content_negotiation\'))\n+ self.assertTrue(hasattr(self.settings, "use_content_negotiation"))\n \n def test_use_path_negotiation_exists(self):\n- self.assertTrue(hasattr(self.settings, \'use_path_negotiation\'))\n+ self.assertTrue(hasattr(self.settings, "use_path_negotiation"))\n \n def test_use_cookie_negotiation_exists(self):\n- self.assertTrue(hasattr(self.settings, \'use_cookie_negotiation\'))\n+ self.assertTrue(hasattr(self.settings, "use_cookie_negotiation"))\n \n def test_authenticated_users_only(self):\n- self.assertTrue(hasattr(self.settings, \'authenticated_users_only\'))\n+ self.assertTrue(hasattr(self.settings, "authenticated_users_only"))\n \n def test_set_cookie_always(self):\n- self.assertTrue(hasattr(self.settings, \'set_cookie_always\'))\n+ self.assertTrue(hasattr(self.settings, "set_cookie_always"))\n \n def test_use_subdomain_negotiation(self):\n- self.assertTrue(hasattr(self.settings, \'use_subdomain_negotiation\'))\n+ self.assertTrue(hasattr(self.settings, "use_subdomain_negotiation"))\n \n def test_use_cctld_negotiation(self):\n- self.assertTrue(hasattr(self.settings, \'use_cctld_negotiation\'))\n+ self.assertTrue(hasattr(self.settings, "use_cctld_negotiation"))\n \n def test_use_request_negotiation(self):\n- self.assertTrue(hasattr(self.settings, \'use_request_negotiation\'))\n+ self.assertTrue(hasattr(self.settings, "use_request_negotiation"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_mail.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_mail.py\nindex dfbbb241dd..7f87c09fcf 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_mail.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_mail.py\n@@ -16,23 +16,23 @@ class MailRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- IMailSchema, prefix="plone")\n+ self.settings = registry.forInterface(IMailSchema, prefix="plone")\n \n def test_mail_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="mail-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="mail-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_mail_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'MailHost\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "MailHost"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_mail_smtp_host_setting(self):\n- self.assertTrue(hasattr(self.settings, \'smtp_host\'))\n+ self.assertTrue(hasattr(self.settings, "smtp_host"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_markup.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_markup.py\nindex ffdae9d135..0581f64abe 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_markup.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_markup.py\n@@ -9,34 +9,34 @@\n \n \n class MarkupRegistryIntegrationTest(unittest.TestCase):\n- """Test plone.app.registry based markup storage.\n- """\n+ """Test plone.app.registry based markup storage."""\n \n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n self.settings = registry.forInterface(IMarkupSchema, prefix="plone")\n \n def test_markup_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="markup-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="markup-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_markup_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'MarkupSettings\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "MarkupSettings"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_default_type_exists(self):\n- self.assertTrue(hasattr(self.settings, \'default_type\'))\n+ self.assertTrue(hasattr(self.settings, "default_type"))\n \n def test_allowed_types_exists(self):\n- self.assertTrue(hasattr(self.settings, \'allowed_types\'))\n+ self.assertTrue(hasattr(self.settings, "allowed_types"))\n \n def test_markdown_extensions_exists(self):\n- self.assertTrue(hasattr(self.settings, \'markdown_extensions\'))\n+ self.assertTrue(hasattr(self.settings, "markdown_extensions"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_navigation.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_navigation.py\nindex 70c54a5fd5..d6fe40b8a3 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_navigation.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_navigation.py\n@@ -16,38 +16,38 @@ class NavigationRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- INavigationSchema, prefix="plone")\n+ self.settings = registry.forInterface(INavigationSchema, prefix="plone")\n \n def test_navigation_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="navigation-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="navigation-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_navigation_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'NavigationSettings\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "NavigationSettings"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_generate_tabs_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'generate_tabs\'))\n+ self.assertTrue(hasattr(self.settings, "generate_tabs"))\n \n def test_nonfolderish_tabs_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'nonfolderish_tabs\'))\n+ self.assertTrue(hasattr(self.settings, "nonfolderish_tabs"))\n \n def test_displayed_types_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'displayed_types\'))\n+ self.assertTrue(hasattr(self.settings, "displayed_types"))\n \n def test_filter_on_workflow_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'filter_on_workflow\'))\n+ self.assertTrue(hasattr(self.settings, "filter_on_workflow"))\n \n def test_workflow_states_to_show_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'workflow_states_to_show\'))\n+ self.assertTrue(hasattr(self.settings, "workflow_states_to_show"))\n \n def test_show_excluded_items_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'show_excluded_items\'))\n+ self.assertTrue(hasattr(self.settings, "show_excluded_items"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_overview.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_overview.py\nindex 54b4fe1e78..9bb2c17895 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_overview.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_overview.py\n@@ -26,7 +26,6 @@ def mock_getUtility4(iface):\n \n \n class TestControlPanel(unittest.TestCase):\n-\n layer = PLONE_INTEGRATION_TESTING\n \n def setUp(self):\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_relations.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_relations.py\nindex 67a37b5fe8..43bcb304af 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_relations.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_relations.py\n@@ -13,19 +13,18 @@\n \n \n class TestRelationsControlpanel(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, (\'Manager\',))\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ("Manager",))\n \n def test_relations_stats(self):\n- self.portal.invokeFactory(\'Document\', id=\'doc1\', title=\'doc1\')\n- doc1 = self.portal[\'doc1\']\n- self.portal.invokeFactory(\'Document\', id=\'doc2\', title=\'doc2\')\n- doc2 = self.portal[\'doc2\']\n+ self.portal.invokeFactory("Document", id="doc1", title="doc1")\n+ doc1 = self.portal["doc1"]\n+ self.portal.invokeFactory("Document", id="doc2", title="doc2")\n+ doc2 = self.portal["doc2"]\n intids = getUtility(IIntIds)\n doc1.relatedItems = PersistentList()\n doc1.relatedItems.append(RelationValue(intids.getId(doc2)))\n@@ -34,19 +33,19 @@ def test_relations_stats(self):\n # api.relation.create(doc1, doc2, \'relatedItems\')\n \n stats, broken = get_relations_stats()\n- self.assertEqual(dict(stats), {\'relatedItems\': 1})\n+ self.assertEqual(dict(stats), {"relatedItems": 1})\n self.assertEqual(dict(broken), {})\n- view = getMultiAdapter((self.portal, self.request), name=\'inspect-relations\')\n+ view = getMultiAdapter((self.portal, self.request), name="inspect-relations")\n self.assertTrue(view())\n- self.assertTrue(view(relation=\'relatedItems\'))\n+ self.assertTrue(view(relation="relatedItems"))\n \n def test_relations_stats_broken(self):\n- self.portal.invokeFactory(\'Document\', id=\'doc1\', title=\'doc1\')\n- doc1 = self.portal[\'doc1\']\n- self.portal.invokeFactory(\'Document\', id=\'doc2\', title=\'doc2\')\n- doc2 = self.portal[\'doc2\']\n- self.portal.invokeFactory(\'Document\', id=\'doc3\', title=\'doc3\')\n- doc3 = self.portal[\'doc3\']\n+ self.portal.invokeFactory("Document", id="doc1", title="doc1")\n+ doc1 = self.portal["doc1"]\n+ self.portal.invokeFactory("Document", id="doc2", title="doc2")\n+ doc2 = self.portal["doc2"]\n+ self.portal.invokeFactory("Document", id="doc3", title="doc3")\n+ doc3 = self.portal["doc3"]\n \n intids = getUtility(IIntIds)\n doc1.relatedItems = PersistentList()\n@@ -56,21 +55,21 @@ def test_relations_stats_broken(self):\n # api.relation.create(doc1, doc2, \'relatedItems\')\n # api.relation.create(doc1, doc3, \'relatedItems\')\n \n- self.portal._delObject(\'doc2\')\n+ self.portal._delObject("doc2")\n stats, broken = get_relations_stats()\n- self.assertEqual(dict(stats), {\'relatedItems\': 1})\n- self.assertEqual(dict(broken), {\'relatedItems\': 1})\n- view = getMultiAdapter((self.portal, self.request), name=\'inspect-relations\')\n+ self.assertEqual(dict(stats), {"relatedItems": 1})\n+ self.assertEqual(dict(broken), {"relatedItems": 1})\n+ view = getMultiAdapter((self.portal, self.request), name="inspect-relations")\n self.assertTrue(view())\n- self.assertTrue(view(relation=\'relatedItems\'))\n+ self.assertTrue(view(relation="relatedItems"))\n \n def test_rebuild_relations(self):\n- self.portal.invokeFactory(\'Document\', id=\'doc1\', title=\'doc1\')\n- doc1 = self.portal[\'doc1\']\n- self.portal.invokeFactory(\'Document\', id=\'doc2\', title=\'doc2\')\n- doc2 = self.portal[\'doc2\']\n- self.portal.invokeFactory(\'Document\', id=\'doc3\', title=\'doc3\')\n- doc3 = self.portal[\'doc3\']\n+ self.portal.invokeFactory("Document", id="doc1", title="doc1")\n+ doc1 = self.portal["doc1"]\n+ self.portal.invokeFactory("Document", id="doc2", title="doc2")\n+ doc2 = self.portal["doc2"]\n+ self.portal.invokeFactory("Document", id="doc3", title="doc3")\n+ doc3 = self.portal["doc3"]\n intids = getUtility(IIntIds)\n doc1_intid = intids.getId(doc1)\n doc2_intid = intids.getId(doc2)\n@@ -87,15 +86,15 @@ def test_rebuild_relations(self):\n self.portal.portal_catalog.searchResults({})\n \n stats, broken = get_relations_stats()\n- self.assertEqual(dict(stats), {\'relatedItems\': 2})\n+ self.assertEqual(dict(stats), {"relatedItems": 2})\n self.assertEqual(dict(broken), {})\n \n- view = getMultiAdapter((self.portal, self.request), name=\'rebuild-relations\')\n+ view = getMultiAdapter((self.portal, self.request), name="rebuild-relations")\n results = view(rebuild=True)\n \n # relations are the same after a rebuild\n stats, broken = get_relations_stats()\n- self.assertEqual(dict(stats), {\'relatedItems\': 2})\n+ self.assertEqual(dict(stats), {"relatedItems": 2})\n self.assertEqual(dict(broken), {})\n \n # intids are not changed\n@@ -107,26 +106,26 @@ def test_rebuild_relations(self):\n self.assertEqual(doc3_intid, doc3_intid_after)\n \n # break a relation\n- self.portal._delObject(\'doc2\')\n+ self.portal._delObject("doc2")\n \n stats, broken = get_relations_stats()\n- self.assertEqual(dict(stats), {\'relatedItems\': 1})\n- self.assertEqual(dict(broken), {\'relatedItems\': 1})\n+ self.assertEqual(dict(stats), {"relatedItems": 1})\n+ self.assertEqual(dict(broken), {"relatedItems": 1})\n \n # broken relations are gone after rebuilding\n- view = getMultiAdapter((self.portal, self.request), name=\'rebuild-relations\')\n+ view = getMultiAdapter((self.portal, self.request), name="rebuild-relations")\n results = view(rebuild=True)\n stats, broken = get_relations_stats()\n- self.assertEqual(dict(stats), {\'relatedItems\': 1})\n+ self.assertEqual(dict(stats), {"relatedItems": 1})\n self.assertEqual(dict(broken), {})\n \n def test_rebuild_relations_with_intid(self):\n- self.portal.invokeFactory(\'Document\', id=\'doc1\', title=\'doc1\')\n- doc1 = self.portal[\'doc1\']\n- self.portal.invokeFactory(\'Document\', id=\'doc2\', title=\'doc2\')\n- doc2 = self.portal[\'doc2\']\n- self.portal.invokeFactory(\'Document\', id=\'doc3\', title=\'doc3\')\n- doc3 = self.portal[\'doc3\']\n+ self.portal.invokeFactory("Document", id="doc1", title="doc1")\n+ doc1 = self.portal["doc1"]\n+ self.portal.invokeFactory("Document", id="doc2", title="doc2")\n+ doc2 = self.portal["doc2"]\n+ self.portal.invokeFactory("Document", id="doc3", title="doc3")\n+ doc3 = self.portal["doc3"]\n intids = getUtility(IIntIds)\n doc1_intid = intids.getId(doc1)\n doc2_intid = intids.getId(doc2)\n@@ -142,15 +141,15 @@ def test_rebuild_relations_with_intid(self):\n self.portal.portal_catalog.searchResults({})\n \n stats, broken = get_relations_stats()\n- self.assertEqual(dict(stats), {\'relatedItems\': 2})\n+ self.assertEqual(dict(stats), {"relatedItems": 2})\n self.assertEqual(dict(broken), {})\n \n- view = getMultiAdapter((self.portal, self.request), name=\'rebuild-relations\')\n+ view = getMultiAdapter((self.portal, self.request), name="rebuild-relations")\n results = view(rebuild=True, flush_and_rebuild_intids=True)\n \n # relations are the same after a rebuild\n stats, broken = get_relations_stats()\n- self.assertEqual(dict(stats), {\'relatedItems\': 2})\n+ self.assertEqual(dict(stats), {"relatedItems": 2})\n self.assertEqual(dict(broken), {})\n \n # intids are now changed\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_search.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_search.py\nindex ebf06c1e1f..2035732ce4 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_search.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_search.py\n@@ -16,29 +16,29 @@ class SearchRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ISearchSchema, prefix="plone")\n+ self.settings = registry.forInterface(ISearchSchema, prefix="plone")\n \n def test_search_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="search-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="search-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_search_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'SearchSettings\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "SearchSettings"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_enable_livesearch_attribute_exists(self):\n- self.assertTrue(hasattr(self.settings, \'enable_livesearch\'))\n+ self.assertTrue(hasattr(self.settings, "enable_livesearch"))\n \n def test_types_not_searched(self):\n- self.assertTrue(hasattr(self.settings, \'types_not_searched\'))\n+ self.assertTrue(hasattr(self.settings, "types_not_searched"))\n \n def test_sort_on(self):\n- self.assertTrue(hasattr(self.settings, \'sort_on\'))\n+ self.assertTrue(hasattr(self.settings, "sort_on"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_security.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_security.py\nindex c7025e5f33..4b167544af 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_security.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_security.py\n@@ -18,39 +18,39 @@ class SecurityRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ISecuritySchema, prefix="plone")\n+ self.settings = registry.forInterface(ISecuritySchema, prefix="plone")\n \n def test_security_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="security-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="security-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_plone_app_registry_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n self.assertTrue(\n- \'plone.app.registry\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()])\n+ "plone.app.registry"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_enable_self_reg_setting(self):\n- self.assertTrue(hasattr(self.settings, \'enable_self_reg\'))\n+ self.assertTrue(hasattr(self.settings, "enable_self_reg"))\n \n def test_enable_user_pwd_choice_setting(self):\n- self.assertTrue(hasattr(self.settings, \'enable_user_pwd_choice\'))\n+ self.assertTrue(hasattr(self.settings, "enable_user_pwd_choice"))\n \n def test_enable_user_folders_setting(self):\n- self.assertTrue(hasattr(self.settings, \'enable_user_folders\'))\n+ self.assertTrue(hasattr(self.settings, "enable_user_folders"))\n \n def test_allow_anon_views_about_setting(self):\n- self.assertTrue(hasattr(self.settings, \'allow_anon_views_about\'))\n+ self.assertTrue(hasattr(self.settings, "allow_anon_views_about"))\n \n def test_use_email_as_login_setting(self):\n- self.assertTrue(hasattr(self.settings, \'use_email_as_login\'))\n+ self.assertTrue(hasattr(self.settings, "use_email_as_login"))\n \n def test_use_uuid_as_userid_setting(self):\n- self.assertTrue(hasattr(self.settings, \'use_uuid_as_userid\'))\n+ self.assertTrue(hasattr(self.settings, "use_uuid_as_userid"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_site.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_site.py\nindex d3eedb379b..b20d80c064 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_site.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_site.py\n@@ -16,39 +16,35 @@ class SiteRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ISiteSchema,\n- prefix="plone"\n- )\n+ self.settings = registry.forInterface(ISiteSchema, prefix="plone")\n \n def test_site_controlpanel_view(self):\n view = getMultiAdapter(\n- (self.portal, self.portal.REQUEST),\n- name="site-controlpanel"\n+ (self.portal, self.portal.REQUEST), name="site-controlpanel"\n )\n self.assertTrue(view())\n \n def test_site_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'PloneReconfig\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "PloneReconfig"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\n \n def test_site_title_setting(self):\n- self.assertTrue(hasattr(self.settings, \'site_title\'))\n+ self.assertTrue(hasattr(self.settings, "site_title"))\n \n def test_site_logo_setting(self):\n- self.assertTrue(hasattr(self.settings, \'site_logo\'))\n+ self.assertTrue(hasattr(self.settings, "site_logo"))\n \n def test_exposeDCMetaTags_setting(self):\n- self.assertTrue(hasattr(self.settings, \'exposeDCMetaTags\'))\n+ self.assertTrue(hasattr(self.settings, "exposeDCMetaTags"))\n \n def test_webstats_js_setting(self):\n- self.assertTrue(hasattr(self.settings, \'webstats_js\'))\n+ self.assertTrue(hasattr(self.settings, "webstats_js"))\n \n def test_enable_sitemap_setting(self):\n- self.assertTrue(hasattr(self.settings, \'enable_sitemap\'))\n+ self.assertTrue(hasattr(self.settings, "enable_sitemap"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_types.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_types.py\nindex 76e96669d7..9d034ec9a5 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_types.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_types.py\n@@ -16,20 +16,20 @@ class TypesRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- ITypesSchema, prefix="plone")\n+ self.settings = registry.forInterface(ITypesSchema, prefix="plone")\n \n def test_types_controlpanel_view(self):\n- view = getMultiAdapter((self.portal, self.portal.REQUEST),\n- name="content-controlpanel")\n+ view = getMultiAdapter(\n+ (self.portal, self.portal.REQUEST), name="content-controlpanel"\n+ )\n self.assertTrue(view())\n \n def test_editing_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- self.assertTrue(\'TypesSettings\' in [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ])\n+ self.assertTrue(\n+ "TypesSettings"\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ )\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_usergroups.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_usergroups.py\nindex 26c7085fe2..901053fb2f 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_usergroups.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_usergroups.py\n@@ -16,12 +16,10 @@ class TypesRegistryIntegrationTest(unittest.TestCase):\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n registry = getUtility(IRegistry)\n- self.settings = registry.forInterface(\n- IUserGroupsSettingsSchema, prefix="plone"\n- )\n+ self.settings = registry.forInterface(IUserGroupsSettingsSchema, prefix="plone")\n \n def test_usergroups_controlpanel_view(self):\n view = getMultiAdapter(\n@@ -31,17 +29,14 @@ def test_usergroups_controlpanel_view(self):\n \n def test_usergroups_in_controlpanel(self):\n self.controlpanel = getToolByName(self.portal, "portal_controlpanel")\n- actions = [\n- a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()\n- ]\n- self.assertTrue(\'UsersGroups\' in actions)\n- self.assertTrue(\'UsersGroups2\' in actions)\n- self.assertTrue(\'UsersGroupsSettings\' in actions)\n- self.assertTrue(\'MemberFields\' in actions)\n+ actions = [a.getAction(self)["id"] for a in self.controlpanel.listActions()]\n+ self.assertTrue("UsersGroups" in actions)\n+ self.assertTrue("UsersGroups2" in actions)\n+ self.assertTrue("UsersGroupsSettings" in actions)\n+ self.assertTrue("MemberFields" in actions)\n \n def test_many_groups_setting(self):\n- self.assertTrue(hasattr(self.settings, \'many_groups\'))\n+ self.assertTrue(hasattr(self.settings, "many_groups"))\n \n def test_many_users_setting(self):\n- self.assertTrue(hasattr(self.settings, \'many_users\'))\n+ self.assertTrue(hasattr(self.settings, "many_users"))\ndiff --git a/Products/CMFPlone/controlpanel/tests/test_doctests.py b/Products/CMFPlone/controlpanel/tests/test_doctests.py\nindex 75788e32b8..a1b6ebadcc 100644\n--- a/Products/CMFPlone/controlpanel/tests/test_doctests.py\n+++ b/Products/CMFPlone/controlpanel/tests/test_doctests.py\n@@ -6,17 +6,17 @@\n import unittest\n \n \n-tests = (\'../README.rst\',)\n+tests = ("../README.rst",)\n \n \n class Py23DocChecker(doctest.OutputChecker):\n-\n def check_output(self, want, got, optionflags):\n # TODO: Fix tests to use Python 3 syntax\n want = re.sub("u\'(.*?)\'", "\'\\\\1\'", want)\n want = re.sub(\'u"(.*?)"\', \'"\\\\1"\', want)\n return doctest.OutputChecker.check_output(self, want, got, optionflags)\n \n+\n def test_suite():\n return unittest.TestSuite(\n [\n@@ -27,7 +27,6 @@ def test_suite():\n checker=Py23DocChecker(),\n ),\n layer=PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING,\n-\n )\n for ft in tests\n ]\ndiff --git a/Products/CMFPlone/controlpanel/utils.py b/Products/CMFPlone/controlpanel/utils.py\nindex 50faf317ac..278ed0a48d 100644\n--- a/Products/CMFPlone/controlpanel/utils.py\n+++ b/Products/CMFPlone/controlpanel/utils.py\n@@ -3,11 +3,11 @@\n import logging\n \n \n-logger = logging.getLogger(\'Products.CMFPlone.controlpanel\')\n+logger = logging.getLogger("Products.CMFPlone.controlpanel")\n \n \n def migrate_to_email_login(context):\n- pas = getToolByName(context, \'acl_users\')\n+ pas = getToolByName(context, "acl_users")\n \n # We want the login name to be lowercase here. This is new in\n # PAS. Using \'manage_changeProperties\' would change the login\n@@ -15,14 +15,14 @@ def migrate_to_email_login(context):\n # and set the lowercase email address as login name, instead of\n # the lower case user id.\n # pas.manage_changeProperties(login_transform=\'lower\')\n- pas.login_transform = \'lower\'\n+ pas.login_transform = "lower"\n \n # Update the users.\n for user in pas.getUsers():\n if user is None:\n continue\n user_id = user.getUserId()\n- email = user.getProperty(\'email\', \'\')\n+ email = user.getProperty("email", "")\n if email:\n login_name = pas.applyTransform(email)\n pas.updateLoginName(user_id, login_name)\n@@ -31,14 +31,14 @@ def migrate_to_email_login(context):\n \n \n def migrate_from_email_login(context):\n- pas = getToolByName(context, \'acl_users\')\n+ pas = getToolByName(context, "acl_users")\n \n # Whether the login name is lowercase or not does not really\n # matter for this use case, but it may be better not to change\n # it at this point.\n \n # XXX\n- pas.login_transform = \'\'\n+ pas.login_transform = ""\n \n # We do want to update the users.\n for user in pas.getUsers():\ndiff --git a/Products/CMFPlone/controlpanel/widgets.py b/Products/CMFPlone/controlpanel/widgets.py\nindex 4808edd074..b10b1699d2 100644\n--- a/Products/CMFPlone/controlpanel/widgets.py\n+++ b/Products/CMFPlone/controlpanel/widgets.py\n@@ -11,14 +11,16 @@ def isChecked(self, term):\n \n def extract(self, default=NO_VALUE):\n tokens = [t.token for t in self.terms]\n- if self.name not in self.request and\\\n- self.name + \'-empty-marker\' in self.request:\n+ if (\n+ self.name not in self.request\n+ and self.name + "-empty-marker" in self.request\n+ ):\n return tokens\n value = self.request.get(self.name, default)\n if value == default:\n return value\n if not isinstance(value, (tuple, list)):\n- value = (value, )\n+ value = (value,)\n for token in value:\n if token in tokens:\n tokens.remove(token)\ndiff --git a/Products/CMFPlone/defaultpage.py b/Products/CMFPlone/defaultpage.py\nindex b83a13acf1..bda6822239 100644\n--- a/Products/CMFPlone/defaultpage.py\n+++ b/Products/CMFPlone/defaultpage.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.defaultpage\', \'Version 7.0\')\n+moved("plone.base.defaultpage", "Version 7.0")\ndiff --git a/Products/CMFPlone/earlypatches/security.py b/Products/CMFPlone/earlypatches/security.py\nindex f0ad36b657..de7cabb010 100644\n--- a/Products/CMFPlone/earlypatches/security.py\n+++ b/Products/CMFPlone/earlypatches/security.py\n@@ -16,6 +16,8 @@ def traverse(self, name, ignored):\n if not name:\n raise TraversalError(self.context, name)\n return old_traverse(self, name, ignored)\n+\n+\n namespace.view.traverse = traverse\n \n # 3. be sure to check Access contents information permission for FTP users\n@@ -26,8 +28,8 @@ def traverse(self, name, ignored):\n from AccessControl import getSecurityManager\n from OFS.ObjectManager import ObjectManager\n from zExceptions import Unauthorized\n- ObjectManager.__old_manage_FTPlist = ObjectManager.manage_FTPlist\n \n+ ObjectManager.__old_manage_FTPlist = ObjectManager.manage_FTPlist\n \n def manage_FTPlist(self, REQUEST):\n """Returns a directory listing consisting of a tuple of\n@@ -38,10 +40,13 @@ def manage_FTPlist(self, REQUEST):\n In the case of non-foldoid objects it should return a single\n tuple (id,stat) representing itself."""\n \n- if not getSecurityManager().checkPermission(\'Access contents information\', self):\n- raise Unauthorized(\'Not allowed to access contents.\')\n+ if not getSecurityManager().checkPermission(\n+ "Access contents information", self\n+ ):\n+ raise Unauthorized("Not allowed to access contents.")\n \n return self.__old_manage_FTPlist(REQUEST)\n+\n ObjectManager.manage_FTPlist = manage_FTPlist\n \n # 4. Make sure z3c.form widgets don\'t get declared as public\n@@ -52,9 +57,11 @@ def manage_FTPlist(self, REQUEST):\n \n \n def require(self, *args, **kw):\n- if self._ClassDirective__class.__module__.startswith(\'z3c.form.browser\'):\n+ if self._ClassDirective__class.__module__.startswith("z3c.form.browser"):\n return\n return old_require(self, *args, **kw)\n+\n+\n ClassDirective.require = require\n \n # 5. Check return value of getToolByName\ndiff --git a/Products/CMFPlone/events.py b/Products/CMFPlone/events.py\nindex e8ffce63ac..77baf900f6 100644\n--- a/Products/CMFPlone/events.py\n+++ b/Products/CMFPlone/events.py\n@@ -23,17 +23,17 @@ def profileImportedEventHandler(event):\n profile_id = event.profile_id\n if profile_id is None:\n return\n- profile_id = profile_id.replace(\'profile-\', \'\')\n+ profile_id = profile_id.replace("profile-", "")\n gs = event.tool\n installed_version = gs.getLastVersionForProfile(profile_id)\n- if installed_version == (\'latest\',):\n+ if installed_version == ("latest",):\n qi = get_installer(gs, gs.REQUEST)\n actual_version = qi.get_latest_upgrade_step(profile_id)\n gs.setLastVersionForProfile(profile_id, actual_version)\n \n \n def removeBase(event):\n- """ Make Zope not to inject a tag into the returned HTML\n+ """Make Zope not to inject a tag into the returned HTML\n https://dev.plone.org/ticket/13705\n """\n event.request.response.base = None\ndiff --git a/Products/CMFPlone/exportimport/controlpanel.py b/Products/CMFPlone/exportimport/controlpanel.py\nindex 0870d8f25a..8e47b022a4 100644\n--- a/Products/CMFPlone/exportimport/controlpanel.py\n+++ b/Products/CMFPlone/exportimport/controlpanel.py\n@@ -32,17 +32,17 @@ class ControlPanelXMLAdapter(XMLAdapterBase):\n \n __used_for__ = IControlPanel\n \n- _LOGGER_ID = \'controlpanel\'\n+ _LOGGER_ID = "controlpanel"\n \n- name = \'controlpanel\'\n+ name = "controlpanel"\n \n def _exportNode(self):\n """\n Export the object as a DOM node.\n """\n- node = self._getObjectNode(\'object\')\n+ node = self._getObjectNode("object")\n node.appendChild(self._extractConfiglets())\n- self._logger.info(\'Control panel exported.\')\n+ self._logger.info("Control panel exported.")\n return node\n \n def _importNode(self, node):\n@@ -50,7 +50,7 @@ def _importNode(self, node):\n Import the object from the DOM node.\n """\n self._initProvider(node)\n- self._logger.info(\'Control panel imported.\')\n+ self._logger.info("Control panel imported.")\n \n def _initProvider(self, node):\n if self.environ.shouldPurge():\n@@ -74,21 +74,21 @@ def _extractConfiglets(self):\n \n if actions:\n actions = list(actions)\n- actions.sort(key=lambda action: action.getMapping()[\'id\'])\n+ actions.sort(key=lambda action: action.getMapping()["id"])\n \n for ai in actions:\n mapping = ai.getMapping()\n- child = self._doc.createElement(\'configlet\')\n- child.setAttribute(\'action_id\', mapping[\'id\'])\n- child.setAttribute(\'category\', mapping[\'category\'])\n- child.setAttribute(\'condition_expr\', mapping[\'condition\'])\n- child.setAttribute(\'title\', mapping[\'title\'])\n- child.setAttribute(\'url_expr\', mapping[\'action\'])\n- child.setAttribute(\'visible\', str(mapping[\'visible\']))\n- child.setAttribute(\'appId\', ai.getAppId())\n- child.setAttribute(\'icon_expr\', mapping[\'icon_expr\'])\n- for permission in mapping[\'permissions\']:\n- sub = self._doc.createElement(\'permission\')\n+ child = self._doc.createElement("configlet")\n+ child.setAttribute("action_id", mapping["id"])\n+ child.setAttribute("category", mapping["category"])\n+ child.setAttribute("condition_expr", mapping["condition"])\n+ child.setAttribute("title", mapping["title"])\n+ child.setAttribute("url_expr", mapping["action"])\n+ child.setAttribute("visible", str(mapping["visible"]))\n+ child.setAttribute("appId", ai.getAppId())\n+ child.setAttribute("icon_expr", mapping["icon_expr"])\n+ for permission in mapping["permissions"]:\n+ sub = self._doc.createElement("permission")\n sub.appendChild(self._doc.createTextNode(permission))\n child.appendChild(sub)\n fragment.appendChild(child)\n@@ -97,77 +97,79 @@ def _extractConfiglets(self):\n def _initConfiglets(self, node):\n controlpanel = self.context\n default_domain = "plone"\n- if node.nodeName == \'object\':\n- domain = str(node.getAttribute(\'i18n:domain\'))\n+ if node.nodeName == "object":\n+ domain = str(node.getAttribute("i18n:domain"))\n if domain:\n default_domain = domain\n for child in node.childNodes:\n- if child.nodeName != \'configlet\':\n+ if child.nodeName != "configlet":\n continue\n \n- domain = str(child.getAttribute(\'i18n:domain\'))\n+ domain = str(child.getAttribute("i18n:domain"))\n if not domain:\n domain = default_domain\n \n- action_id = str(child.getAttribute(\'action_id\'))\n+ action_id = str(child.getAttribute("action_id"))\n # Remove previous action with same id and category.\n controlpanel.unregisterConfiglet(action_id)\n- remove = str(child.getAttribute(\'remove\'))\n- if remove.lower() == \'true\':\n+ remove = str(child.getAttribute("remove"))\n+ if remove.lower() == "true":\n continue\n \n- title = Message(str(child.getAttribute(\'title\')), domain=domain)\n- url_expr = str(child.getAttribute(\'url_expr\'))\n- condition_expr = str(child.getAttribute(\'condition_expr\'))\n- icon_expr = str(child.getAttribute(\'icon_expr\'))\n- category = str(child.getAttribute(\'category\'))\n- visible = str(child.getAttribute(\'visible\'))\n- appId = str(child.getAttribute(\'appId\'))\n- if visible.lower() == \'true\':\n+ title = Message(str(child.getAttribute("title")), domain=domain)\n+ url_expr = str(child.getAttribute("url_expr"))\n+ condition_expr = str(child.getAttribute("condition_expr"))\n+ icon_expr = str(child.getAttribute("icon_expr"))\n+ category = str(child.getAttribute("category"))\n+ visible = str(child.getAttribute("visible"))\n+ appId = str(child.getAttribute("appId"))\n+ if visible.lower() == "true":\n visible = 1\n else:\n visible = 0\n \n- permission = \'\'\n+ permission = ""\n for permNode in child.childNodes:\n- if permNode.nodeName == \'permission\':\n+ if permNode.nodeName == "permission":\n for textNode in permNode.childNodes:\n- if textNode.nodeName != \'#text\' or \\\n- not textNode.nodeValue.strip():\n+ if (\n+ textNode.nodeName != "#text"\n+ or not textNode.nodeValue.strip()\n+ ):\n continue\n permission = str(textNode.nodeValue)\n break # only one permission is allowed\n if permission:\n break\n \n- controlpanel.registerConfiglet(id=action_id,\n- name=title,\n- action=url_expr,\n- appId=appId,\n- condition=condition_expr,\n- category=category,\n- permission=permission,\n- visible=visible,\n- icon_expr=icon_expr)\n+ controlpanel.registerConfiglet(\n+ id=action_id,\n+ name=title,\n+ action=url_expr,\n+ appId=appId,\n+ condition=condition_expr,\n+ category=category,\n+ permission=permission,\n+ visible=visible,\n+ icon_expr=icon_expr,\n+ )\n \n \n def importControlPanel(context):\n- """Import Plone control panel.\n- """\n+ """Import Plone control panel."""\n site = context.getSite()\n- tool = getToolByName(site, \'portal_controlpanel\', None)\n+ tool = getToolByName(site, "portal_controlpanel", None)\n if tool is None:\n return\n \n- importObjects(tool, \'\', context)\n+ importObjects(tool, "", context)\n \n \n def exportControlPanel(context):\n- """Export actions tool.\n- """\n+ """Export actions tool."""\n site = context.getSite()\n- tool = getToolByName(site, \'portal_controlpanel\', None)\n+ tool = getToolByName(site, "portal_controlpanel", None)\n if tool is None:\n return\n \n- exportObjects(tool, \'\', context)\n+ exportObjects(tool, "", context)\ndiff --git a/Products/CMFPlone/exportimport/memberdata_properties.py b/Products/CMFPlone/exportimport/memberdata_properties.py\nindex 5a7c948d07..4c8fd85843 100644\n--- a/Products/CMFPlone/exportimport/memberdata_properties.py\n+++ b/Products/CMFPlone/exportimport/memberdata_properties.py\n@@ -8,15 +8,14 @@\n from zope.component import queryMultiAdapter\n \n \n-_FILENAME = \'memberdata_properties.xml\'\n+_FILENAME = "memberdata_properties.xml"\n \n \n def importMemberDataProperties(context):\n- """ Import MemberData tool properties.\n- """\n+ """Import MemberData tool properties."""\n site = context.getSite()\n- logger = context.getLogger(\'memberdata\')\n- ptool = getToolByName(site, \'portal_memberdata\')\n+ logger = context.getLogger("memberdata")\n+ ptool = getToolByName(site, "portal_memberdata")\n \n body = context.readDataFile(_FILENAME)\n if body is None:\n@@ -24,26 +23,25 @@ def importMemberDataProperties(context):\n \n importer = queryMultiAdapter((ptool, context), IBody)\n if importer is None:\n- logger.warning(\'Import adapter missing.\')\n+ logger.warning("Import adapter missing.")\n return\n \n importer.body = body\n- logger.info(\'MemberData tool imported.\')\n+ logger.info("MemberData tool imported.")\n \n \n def exportMemberDataProperties(context):\n- """ Export MemberData tool properties .\n- """\n+ """Export MemberData tool properties ."""\n site = context.getSite()\n- logger = context.getLogger(\'memberdata\')\n- ptool = getToolByName(site, \'portal_memberdata\', None)\n+ logger = context.getLogger("memberdata")\n+ ptool = getToolByName(site, "portal_memberdata", None)\n if ptool is None:\n return\n \n exporter = queryMultiAdapter((ptool, context), IBody)\n if exporter is None:\n- logger.warning(\'Export adapter missing.\')\n+ logger.warning("Export adapter missing.")\n return\n \n context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)\n- logger.info(\'MemberData tool exported.\')\n+ logger.info("MemberData tool exported.")\ndiff --git a/Products/CMFPlone/exportimport/propertiestool.py b/Products/CMFPlone/exportimport/propertiestool.py\nindex 5838ef5d17..94e21a1326 100644\n--- a/Products/CMFPlone/exportimport/propertiestool.py\n+++ b/Products/CMFPlone/exportimport/propertiestool.py\n@@ -15,15 +15,14 @@\n from zope.component import queryMultiAdapter\n \n \n-_FILENAME = \'propertiestool.xml\'\n+_FILENAME = "propertiestool.xml"\n \n \n def importPloneProperties(context):\n- """ Import plone properties tool.\n- """\n+ """Import plone properties tool."""\n site = context.getSite()\n- logger = context.getLogger(\'propertiestool\')\n- ptool = getToolByName(site, \'portal_properties\')\n+ logger = context.getLogger("propertiestool")\n+ ptool = getToolByName(site, "portal_properties")\n \n body = context.readDataFile(_FILENAME)\n if body is None:\n@@ -31,51 +30,46 @@ def importPloneProperties(context):\n \n importer = queryMultiAdapter((ptool, context), IBody)\n if importer is None:\n- logger.warning(\'Import adapter missing.\')\n+ logger.warning("Import adapter missing.")\n return\n \n importer.body = body\n- logger.info(\'Properties tool imported.\')\n+ logger.info("Properties tool imported.")\n \n \n def exportPloneProperties(context):\n- """ Export plone properties tool.\n- """\n+ """Export plone properties tool."""\n site = context.getSite()\n- logger = context.getLogger(\'propertiestool\')\n- ptool = getToolByName(site, \'portal_properties\', None)\n+ logger = context.getLogger("propertiestool")\n+ ptool = getToolByName(site, "portal_properties", None)\n if ptool is None:\n return\n \n exporter = queryMultiAdapter((ptool, context), IBody)\n # IBody(ptool)\n if exporter is None:\n- logger.warning(\'Export adapter missing.\')\n+ logger.warning("Export adapter missing.")\n return\n \n context.writeDataFile(_FILENAME, exporter.body, exporter.mime_type)\n- logger.info(\'Properties tool exported.\')\n+ logger.info("Properties tool exported.")\n \n \n-class SimpleItemWithPropertiesXMLAdapter(\n- XMLAdapterBase, PropertyManagerHelpers):\n+class SimpleItemWithPropertiesXMLAdapter(XMLAdapterBase, PropertyManagerHelpers):\n \n- """Node im- and exporter for SimpleItemWithProperties.\n- """\n+ """Node im- and exporter for SimpleItemWithProperties."""\n \n __used_for__ = ISimpleItemWithProperties\n \n def _exportNode(self):\n- """Export the object as a DOM node.\n- """\n- #self._doc = doc\n- node = self._getObjectNode(\'object\')\n+ """Export the object as a DOM node."""\n+ # self._doc = doc\n+ node = self._getObjectNode("object")\n node.appendChild(self._extractProperties())\n return node\n \n def _importNode(self, node):\n- """Import the object from the DOM node.\n- """\n+ """Import the object from the DOM node."""\n self._initProperties(node)\n \n node = property(_exportNode, _importNode)\n@@ -83,23 +77,20 @@ def _importNode(self, node):\n \n class PlonePropertiesToolXMLAdapter(XMLAdapterBase, ObjectManagerHelpers):\n \n- """Node im- and exporter for Plone PropertiesTool.\n- """\n+ """Node im- and exporter for Plone PropertiesTool."""\n \n __used_for__ = IPlonePropertiesTool\n \n def _exportNode(self):\n- """Export the object as a DOM node.\n- """\n- #self._doc = doc\n- node = self._getObjectNode(\'object\')\n- #node.setAttribute(\'xmlns:i18n\', I18NURI)\n+ """Export the object as a DOM node."""\n+ # self._doc = doc\n+ node = self._getObjectNode("object")\n+ # node.setAttribute(\'xmlns:i18n\', I18NURI)\n node.appendChild(self._extractObjects())\n return node\n \n def _importNode(self, node):\n- """Import the object from the DOM node.\n- """\n+ """Import the object from the DOM node."""\n if self.environ.shouldPurge():\n self._purgeObjects()\n \n@@ -112,19 +103,19 @@ def _initObjects(self, node):\n # constructor from Products.meta_type and\n # SimpleItemWithProperties doesn\'t get registered there.\n for child in node.childNodes:\n- if child.nodeName != \'object\':\n+ if child.nodeName != "object":\n continue\n- if child.hasAttribute(\'deprecated\'):\n+ if child.hasAttribute("deprecated"):\n continue\n parent = self.context\n \n- obj_id = str(child.getAttribute(\'name\'))\n+ obj_id = str(child.getAttribute("name"))\n if obj_id not in parent:\n parent._setObject(obj_id, SimpleItemWithProperties(obj_id))\n \n- if child.hasAttribute(\'insert-before\'):\n- insert_before = child.getAttribute(\'insert-before\')\n- if insert_before == \'*\':\n+ if child.hasAttribute("insert-before"):\n+ insert_before = child.getAttribute("insert-before")\n+ if insert_before == "*":\n parent.moveObjectsToTop(obj_id)\n else:\n try:\n@@ -132,9 +123,9 @@ def _initObjects(self, node):\n parent.moveObjectToPosition(obj_id, position)\n except ValueError:\n pass\n- elif child.hasAttribute(\'insert-after\'):\n- insert_after = child.getAttribute(\'insert-after\')\n- if insert_after == \'*\':\n+ elif child.hasAttribute("insert-after"):\n+ insert_after = child.getAttribute("insert-after")\n+ if insert_after == "*":\n parent.moveObjectsToBottom(obj_id)\n else:\n try:\ndiff --git a/Products/CMFPlone/exportimport/tests/base.py b/Products/CMFPlone/exportimport/tests/base.py\nindex dd27aa8351..24d07c68e9 100644\n--- a/Products/CMFPlone/exportimport/tests/base.py\n+++ b/Products/CMFPlone/exportimport/tests/base.py\n@@ -6,10 +6,8 @@\n \n \n class BodyAdapterTestCase(BodyAdapterTestCase, unittest.TestCase):\n-\n layer = UNIT_TESTING\n \n \n class NodeAdapterTestCase(NodeAdapterTestCase, unittest.TestCase):\n-\n layer = UNIT_TESTING\ndiff --git a/Products/CMFPlone/exportimport/tests/testControlPanel.py b/Products/CMFPlone/exportimport/tests/testControlPanel.py\nindex dbe17bd76a..a3582be816 100644\n--- a/Products/CMFPlone/exportimport/tests/testControlPanel.py\n+++ b/Products/CMFPlone/exportimport/tests/testControlPanel.py\n@@ -21,31 +21,31 @@\n \n \n class ControlPanelXMLAdapterTests(BodyAdapterTestCase):\n-\n def _getTargetClass(self):\n from Products.CMFPlone.exportimport.controlpanel import ControlPanelXMLAdapter\n+\n return ControlPanelXMLAdapter\n \n def _populate(self, obj):\n obj.registerConfiglet(\n- id=\'QuickInstaller\',\n- name=\'Add/Remove Products\',\n- action=\'string:${portal_url}/prefs_install_products_form\',\n- permission=\'Manage portal\',\n- category=\'Plone\',\n+ id="QuickInstaller",\n+ name="Add/Remove Products",\n+ action="string:${portal_url}/prefs_install_products_form",\n+ permission="Manage portal",\n+ category="Plone",\n visible=True,\n- appId=\'QuickInstaller\',\n- icon_expr=\'string:${portal_url}/product_icon.png\',\n+ appId="QuickInstaller",\n+ icon_expr="string:${portal_url}/product_icon.png",\n )\n \n def setUp(self):\n from Products.GenericSetup.interfaces import IBody\n from Products.GenericSetup.interfaces import ISetupEnviron\n- self.site = Folder(\'site\')\n+\n+ self.site = Folder("site")\n self.site.portal_control_panel = PloneControlPanel()\n provideUtility(self.site.portal_control_panel, IControlPanel)\n- provideAdapter(self._getTargetClass(),\n- (IControlPanel, ISetupEnviron), IBody)\n+ provideAdapter(self._getTargetClass(), (IControlPanel, ISetupEnviron), IBody)\n self._obj = self.site.portal_control_panel\n self._BODY = _CONTROLPANEL_XML\n \n@@ -53,6 +53,7 @@ def setUp(self):\n def test_suite():\n from unittest import makeSuite\n from unittest import TestSuite\n+\n suite = TestSuite()\n suite.addTest(makeSuite(ControlPanelXMLAdapterTests))\n return suite\ndiff --git a/Products/CMFPlone/exportimport/tests/testPropertiesTool.py b/Products/CMFPlone/exportimport/tests/testPropertiesTool.py\nindex 44dcbaa8a5..48e13f8075 100644\n--- a/Products/CMFPlone/exportimport/tests/testPropertiesTool.py\n+++ b/Products/CMFPlone/exportimport/tests/testPropertiesTool.py\n@@ -26,45 +26,44 @@\n \n \n class PropertySheetXMLAdapterTests(BodyAdapterTestCase):\n-\n def _getTargetClass(self):\n from Products.CMFPlone.exportimport.propertiestool import (\n SimpleItemWithPropertiesXMLAdapter,\n )\n+\n return SimpleItemWithPropertiesXMLAdapter\n \n def _populate(self, obj):\n- obj.manage_changeProperties(title=\'Site wide properties\')\n- obj.manage_addProperty(\n- \'displayPublicationDateInByline\', True, \'boolean\')\n+ obj.manage_changeProperties(title="Site wide properties")\n+ obj.manage_addProperty("displayPublicationDateInByline", True, "boolean")\n \n def setUp(self):\n from plone.base.interfaces import ISimpleItemWithProperties\n from Products.GenericSetup.interfaces import IBody\n from Products.GenericSetup.interfaces import ISetupEnviron\n+\n provideAdapter(\n- self._getTargetClass(),\n- (ISimpleItemWithProperties, ISetupEnviron), IBody)\n+ self._getTargetClass(), (ISimpleItemWithProperties, ISetupEnviron), IBody\n+ )\n \n- self._obj = SimpleItemWithProperties(\'site_properties\')\n+ self._obj = SimpleItemWithProperties("site_properties")\n self._BODY = _PROPERTYSHEET_XML\n \n \n class PropertiesToolXMLAdapterTests(BodyAdapterTestCase):\n-\n def _getTargetClass(self):\n from Products.CMFPlone.exportimport.propertiestool import (\n PlonePropertiesToolXMLAdapter,\n )\n+\n return PlonePropertiesToolXMLAdapter\n \n def _populate(self, obj):\n- obj._setObject(\'site_properties\',\n- SimpleItemWithProperties(\'site_properties\'))\n- obj.site_properties.manage_changeProperties(\n- title=\'Site wide properties\')\n+ obj._setObject("site_properties", SimpleItemWithProperties("site_properties"))\n+ obj.site_properties.manage_changeProperties(title="Site wide properties")\n obj.site_properties.manage_addProperty(\n- \'displayPublicationDateInByline\', True, \'boolean\')\n+ "displayPublicationDateInByline", True, "boolean"\n+ )\n \n def setUp(self):\n from plone.base.interfaces import IPropertiesTool\n@@ -74,11 +73,13 @@ def setUp(self):\n )\n from Products.GenericSetup.interfaces import IBody\n from Products.GenericSetup.interfaces import ISetupEnviron\n- provideAdapter(\n- self._getTargetClass(), (IPropertiesTool, ISetupEnviron), IBody)\n+\n+ provideAdapter(self._getTargetClass(), (IPropertiesTool, ISetupEnviron), IBody)\n provideAdapter(\n SimpleItemWithPropertiesXMLAdapter,\n- (ISimpleItemWithProperties, ISetupEnviron), IBody)\n+ (ISimpleItemWithProperties, ISetupEnviron),\n+ IBody,\n+ )\n \n self._obj = PropertiesTool()\n self._BODY = _PROPERTIESTOOL_XML\n@@ -87,6 +88,7 @@ def setUp(self):\n def test_suite():\n from unittest import makeSuite\n from unittest import TestSuite\n+\n suite = TestSuite()\n suite.addTest(makeSuite(PropertySheetXMLAdapterTests))\n suite.addTest(makeSuite(PropertiesToolXMLAdapterTests))\ndiff --git a/Products/CMFPlone/factory.py b/Products/CMFPlone/factory.py\nindex e8f9ae365c..979d88d2d6 100644\n--- a/Products/CMFPlone/factory.py\n+++ b/Products/CMFPlone/factory.py\n@@ -12,10 +12,10 @@\n from zope.lifecycleevent import ObjectCreatedEvent\n \n \n-_TOOL_ID = \'portal_setup\'\n-_DEFAULT_PROFILE = \'Products.CMFPlone:plone\'\n-_TYPES_PROFILE = \'plone.app.contenttypes:default\'\n-_CONTENT_PROFILE = \'plone.app.contenttypes:plone-content\'\n+_TOOL_ID = "portal_setup"\n+_DEFAULT_PROFILE = "Products.CMFPlone:plone"\n+_TYPES_PROFILE = "plone.app.contenttypes:default"\n+_CONTENT_PROFILE = "plone.app.contenttypes:plone-content"\n \n # A little hint for PloneTestCase (pre-Plone 6.0)\n _IMREALLYPLONE5 = True\n@@ -26,100 +26,121 @@\n PLONE52MARKER = True\n PLONE60MARKER = True\n \n-logger = getLogger(\'Plone\')\n+logger = getLogger("Plone")\n \n \n @implementer(INonInstallable)\n class NonInstallable:\n-\n def getNonInstallableProducts(self):\n return [\n- \'CMFDefault\', \'Products.CMFDefault\',\n- \'CMFPlone\', \'Products.CMFPlone\', \'Products.CMFPlone.migrations\',\n- \'CMFTopic\', \'Products.CMFTopic\',\n- \'CMFUid\', \'Products.CMFUid\',\n- \'DCWorkflow\', \'Products.DCWorkflow\',\n- \'PasswordResetTool\', \'Products.PasswordResetTool\',\n- \'PlonePAS\', \'Products.PlonePAS\',\n- \'PloneLanguageTool\', \'Products.PloneLanguageTool\',\n- \'MimetypesRegistry\', \'Products.MimetypesRegistry\',\n- \'PortalTransforms\', \'Products.PortalTransforms\',\n- \'CMFDiffTool\', \'Products.CMFDiffTool\',\n- \'CMFEditions\', \'Products.CMFEditions\',\n- \'Products.NuPlone\',\n- \'borg.localrole\',\n- \'plone.app.caching\',\n- \'plone.app.dexterity\',\n- \'plone.app.discussion\',\n- \'plone.app.event\',\n- \'plone.app.intid\',\n- \'plone.app.linkintegrity\',\n- \'plone.app.querystring\',\n- \'plone.app.registry\',\n- \'plone.app.referenceablebehavior\',\n- \'plone.app.relationfield\',\n- \'plone.app.theming\',\n- \'plone.app.users\',\n- \'plone.app.widgets\',\n- \'plone.app.z3cform\',\n- \'plone.formwidget.recurrence\',\n- \'plone.keyring\',\n- \'plone.outputfilters\',\n- \'plone.portlet.static\',\n- \'plone.portlet.collection\',\n- \'plone.protect\',\n- \'plone.resource\',\n- \'plonetheme.barceloneta\',\n+ "CMFDefault",\n+ "Products.CMFDefault",\n+ "CMFPlone",\n+ "Products.CMFPlone",\n+ "Products.CMFPlone.migrations",\n+ "CMFTopic",\n+ "Products.CMFTopic",\n+ "CMFUid",\n+ "Products.CMFUid",\n+ "DCWorkflow",\n+ "Products.DCWorkflow",\n+ "PasswordResetTool",\n+ "Products.PasswordResetTool",\n+ "PlonePAS",\n+ "Products.PlonePAS",\n+ "PloneLanguageTool",\n+ "Products.PloneLanguageTool",\n+ "MimetypesRegistry",\n+ "Products.MimetypesRegistry",\n+ "PortalTransforms",\n+ "Products.PortalTransforms",\n+ "CMFDiffTool",\n+ "Products.CMFDiffTool",\n+ "CMFEditions",\n+ "Products.CMFEditions",\n+ "Products.NuPlone",\n+ "borg.localrole",\n+ "plone.app.caching",\n+ "plone.app.dexterity",\n+ "plone.app.discussion",\n+ "plone.app.event",\n+ "plone.app.intid",\n+ "plone.app.linkintegrity",\n+ "plone.app.querystring",\n+ "plone.app.registry",\n+ "plone.app.referenceablebehavior",\n+ "plone.app.relationfield",\n+ "plone.app.theming",\n+ "plone.app.users",\n+ "plone.app.widgets",\n+ "plone.app.z3cform",\n+ "plone.formwidget.recurrence",\n+ "plone.keyring",\n+ "plone.outputfilters",\n+ "plone.portlet.static",\n+ "plone.portlet.collection",\n+ "plone.protect",\n+ "plone.resource",\n+ "plonetheme.barceloneta",\n ]\n \n def getNonInstallableProfiles(self):\n- return [_DEFAULT_PROFILE,\n- _CONTENT_PROFILE,\n- \'Products.CMFDiffTool:CMFDiffTool\',\n- \'Products.CMFEditions:CMFEditions\',\n- \'Products.CMFPlone:dependencies\',\n- \'Products.CMFPlone:testfixture\',\n- \'Products.NuPlone:uninstall\',\n- \'Products.MimetypesRegistry:MimetypesRegistry\',\n- \'Products.PasswordResetTool:PasswordResetTool\',\n- \'Products.PortalTransforms:PortalTransforms\',\n- \'Products.PloneLanguageTool:PloneLanguageTool\',\n- \'Products.PlonePAS:PlonePAS\',\n- \'borg.localrole:default\',\n- \'plone.browserlayer:default\',\n- \'plone.keyring:default\',\n- \'plone.outputfilters:default\',\n- \'plone.portlet.static:default\',\n- \'plone.portlet.collection:default\',\n- \'plone.protect:default\',\n- \'plone.app.contenttypes:default\',\n- \'plone.app.dexterity:default\',\n- \'plone.app.discussion:default\',\n- \'plone.app.event:default\',\n- \'plone.app.linkintegrity:default\',\n- \'plone.app.registry:default\',\n- \'plone.app.relationfield:default\',\n- \'plone.app.theming:default\',\n- \'plone.app.users:default\',\n- \'plone.app.versioningbehavior:default\',\n- \'plone.app.z3cform:default\',\n- \'plone.formwidget.recurrence:default\',\n- \'plone.resource:default\',\n- ]\n+ return [\n+ _DEFAULT_PROFILE,\n+ _CONTENT_PROFILE,\n+ "Products.CMFDiffTool:CMFDiffTool",\n+ "Products.CMFEditions:CMFEditions",\n+ "Products.CMFPlone:dependencies",\n+ "Products.CMFPlone:testfixture",\n+ "Products.NuPlone:uninstall",\n+ "Products.MimetypesRegistry:MimetypesRegistry",\n+ "Products.PasswordResetTool:PasswordResetTool",\n+ "Products.PortalTransforms:PortalTransforms",\n+ "Products.PloneLanguageTool:PloneLanguageTool",\n+ "Products.PlonePAS:PlonePAS",\n+ "borg.localrole:default",\n+ "plone.browserlayer:default",\n+ "plone.keyring:default",\n+ "plone.outputfilters:default",\n+ "plone.portlet.static:default",\n+ "plone.portlet.collection:default",\n+ "plone.protect:default",\n+ "plone.app.contenttypes:default",\n+ "plone.app.dexterity:default",\n+ "plone.app.discussion:default",\n+ "plone.app.event:default",\n+ "plone.app.linkintegrity:default",\n+ "plone.app.registry:default",\n+ "plone.app.relationfield:default",\n+ "plone.app.theming:default",\n+ "plone.app.users:default",\n+ "plone.app.versioningbehavior:default",\n+ "plone.app.z3cform:default",\n+ "plone.formwidget.recurrence:default",\n+ "plone.resource:default",\n+ ]\n \n \n def zmi_constructor(context):\n """This is a dummy constructor for the ZMI."""\n url = context.DestinationURL()\n request = context.REQUEST\n- return request.response.redirect(url + \'/@@plone-addsite?site_id=Plone\')\n-\n-\n-def addPloneSite(context, site_id, title=\'Plone site\', description=\'\',\n- profile_id=_DEFAULT_PROFILE,\n- content_profile_id=None, snapshot=False,\n- extension_ids=(), setup_content=True,\n- default_language=\'en\', portal_timezone=\'UTC\'):\n+ return request.response.redirect(url + "/@@plone-addsite?site_id=Plone")\n+\n+\n+def addPloneSite(\n+ context,\n+ site_id,\n+ title="Plone site",\n+ description="",\n+ profile_id=_DEFAULT_PROFILE,\n+ content_profile_id=None,\n+ snapshot=False,\n+ extension_ids=(),\n+ setup_content=True,\n+ default_language="en",\n+ portal_timezone="UTC",\n+):\n """Add a PloneSite to the context."""\n \n site = PloneSite(site_id)\n@@ -133,7 +154,7 @@ def addPloneSite(context, site_id, title=\'Plone site\', description=\'\',\n # prefers non-English and you choose English as language for the Plone\n # Site.\n request = context.REQUEST\n- request[\'HTTP_ACCEPT_LANGUAGE\'] = default_language\n+ request["HTTP_ACCEPT_LANGUAGE"] = default_language\n \n site[_TOOL_ID] = SetupTool(_TOOL_ID)\n setup_tool = site[_TOOL_ID]\n@@ -142,15 +163,15 @@ def addPloneSite(context, site_id, title=\'Plone site\', description=\'\',\n setSite(site)\n \n try:\n- setup_tool.setBaselineContext(\'profile-%s\' % profile_id)\n- setup_tool.runAllImportStepsFromProfile(\'profile-%s\' % profile_id)\n+ setup_tool.setBaselineContext("profile-%s" % profile_id)\n+ setup_tool.runAllImportStepsFromProfile("profile-%s" % profile_id)\n \n reg = queryUtility(IRegistry, context=site)\n- reg[\'plone.portal_timezone\'] = portal_timezone\n- reg[\'plone.available_timezones\'] = [portal_timezone]\n- reg[\'plone.default_language\'] = default_language\n- reg[\'plone.available_languages\'] = [default_language]\n- reg[\'plone.site_title\'] = title\n+ reg["plone.portal_timezone"] = portal_timezone\n+ reg["plone.available_timezones"] = [portal_timezone]\n+ reg["plone.default_language"] = default_language\n+ reg["plone.available_languages"] = [default_language]\n+ reg["plone.site_title"] = title\n \n # Install default content types profile if user do not select "example content"\n # during site creation.\n@@ -168,7 +189,7 @@ def addPloneSite(context, site_id, title=\'Plone site\', description=\'\',\n content_profiles = [_TYPES_PROFILE]\n \n for profile_id in content_profiles:\n- setup_tool.runAllImportStepsFromProfile(f\'profile-{profile_id}\')\n+ setup_tool.runAllImportStepsFromProfile(f"profile-{profile_id}")\n \n props = dict(\n title=title,\n@@ -186,7 +207,7 @@ def addPloneSite(context, site_id, title=\'Plone site\', description=\'\',\n raise\n \n if snapshot is True:\n- setup_tool.createSnapshot(\'initial_configuration\')\n+ setup_tool.createSnapshot("initial_configuration")\n \n return site\n except Exception:\ndiff --git a/Products/CMFPlone/i18nl10n.py b/Products/CMFPlone/i18nl10n.py\nindex 5c7eea59ea..877f59745c 100644\n--- a/Products/CMFPlone/i18nl10n.py\n+++ b/Products/CMFPlone/i18nl10n.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.i18nl10n\', \'Version 7.0\')\n+moved("plone.base.i18nl10n", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/atd.py b/Products/CMFPlone/interfaces/atd.py\nindex e19354b987..95c7b44aa8 100644\n--- a/Products/CMFPlone/interfaces/atd.py\n+++ b/Products/CMFPlone/interfaces/atd.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.atd\', \'Version 7.0\')\n+moved("plone.base.interfaces.atd", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/basetool.py b/Products/CMFPlone/interfaces/basetool.py\nindex 3d9ab298f7..f712501957 100644\n--- a/Products/CMFPlone/interfaces/basetool.py\n+++ b/Products/CMFPlone/interfaces/basetool.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.basetool\', \'Version 7.0\')\n+moved("plone.base.interfaces.basetool", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/breadcrumbs.py b/Products/CMFPlone/interfaces/breadcrumbs.py\nindex 7f3ab83bdc..68f67eb77d 100644\n--- a/Products/CMFPlone/interfaces/breadcrumbs.py\n+++ b/Products/CMFPlone/interfaces/breadcrumbs.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.breadcrumbs\', \'Version 7.0\')\n+moved("plone.base.interfaces.breadcrumbs", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/constrains.py b/Products/CMFPlone/interfaces/constrains.py\nindex f4ac92580c..983d30dac6 100644\n--- a/Products/CMFPlone/interfaces/constrains.py\n+++ b/Products/CMFPlone/interfaces/constrains.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.constrains\', \'Version 7.0\')\n+moved("plone.base.interfaces.constrains", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/controlpanel.py b/Products/CMFPlone/interfaces/controlpanel.py\nindex 9139510242..69143b6f2b 100644\n--- a/Products/CMFPlone/interfaces/controlpanel.py\n+++ b/Products/CMFPlone/interfaces/controlpanel.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.controlpanel\', \'Version 7.0\')\n+moved("plone.base.interfaces.controlpanel", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/defaultpage.py b/Products/CMFPlone/interfaces/defaultpage.py\nindex 2a4e02ccbe..c6738b3788 100644\n--- a/Products/CMFPlone/interfaces/defaultpage.py\n+++ b/Products/CMFPlone/interfaces/defaultpage.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.defaultpage\', \'Version 7.0\')\n+moved("plone.base.interfaces.defaultpage", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/events.py b/Products/CMFPlone/interfaces/events.py\nindex b2d28b6eb0..7e13b86484 100644\n--- a/Products/CMFPlone/interfaces/events.py\n+++ b/Products/CMFPlone/interfaces/events.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.events\', \'Version 7.0\')\n+moved("plone.base.interfaces.events", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/installable.py b/Products/CMFPlone/interfaces/installable.py\nindex 884cd3b384..986709479b 100644\n--- a/Products/CMFPlone/interfaces/installable.py\n+++ b/Products/CMFPlone/interfaces/installable.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.installable\', \'Version 7.0\')\n+moved("plone.base.interfaces.installable", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/interface.py b/Products/CMFPlone/interfaces/interface.py\nindex 33f962c53a..7b44f2d141 100644\n--- a/Products/CMFPlone/interfaces/interface.py\n+++ b/Products/CMFPlone/interfaces/interface.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.interface\', \'Version 7.0\')\n+moved("plone.base.interfaces.interface", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/language.py b/Products/CMFPlone/interfaces/language.py\nindex 0a984adc0f..e89b39ce34 100644\n--- a/Products/CMFPlone/interfaces/language.py\n+++ b/Products/CMFPlone/interfaces/language.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.language\', \'Version 7.0\')\n+moved("plone.base.interfaces.language", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/login.py b/Products/CMFPlone/interfaces/login.py\nindex a6a2b31292..4e2b0c66f5 100644\n--- a/Products/CMFPlone/interfaces/login.py\n+++ b/Products/CMFPlone/interfaces/login.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.login\', \'Version 7.0\')\n+moved("plone.base.interfaces.login", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/migration.py b/Products/CMFPlone/interfaces/migration.py\nindex 7c337fbe0b..f599d29da2 100644\n--- a/Products/CMFPlone/interfaces/migration.py\n+++ b/Products/CMFPlone/interfaces/migration.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.migration\', \'Version 7.0\')\n+moved("plone.base.interfaces.migration", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/password_reset.py b/Products/CMFPlone/interfaces/password_reset.py\nindex dd7d2f429b..77b2b25ef7 100644\n--- a/Products/CMFPlone/interfaces/password_reset.py\n+++ b/Products/CMFPlone/interfaces/password_reset.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.password_reset\', \'Version 7.0\')\n+moved("plone.base.interfaces.password_reset", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/patterns.py b/Products/CMFPlone/interfaces/patterns.py\nindex 38419fac65..2162882ae1 100644\n--- a/Products/CMFPlone/interfaces/patterns.py\n+++ b/Products/CMFPlone/interfaces/patterns.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.patterns\', \'Version 7.0\')\n+moved("plone.base.interfaces.patterns", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/properties.py b/Products/CMFPlone/interfaces/properties.py\nindex 9619c121f0..48a9a0d026 100644\n--- a/Products/CMFPlone/interfaces/properties.py\n+++ b/Products/CMFPlone/interfaces/properties.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.properties\', \'Version 7.0\')\n+moved("plone.base.interfaces.properties", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/resources.py b/Products/CMFPlone/interfaces/resources.py\nindex 198a1045e4..d6d3959b38 100644\n--- a/Products/CMFPlone/interfaces/resources.py\n+++ b/Products/CMFPlone/interfaces/resources.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.resources\', \'Version 7.0\')\n+moved("plone.base.interfaces.resources", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/siteroot.py b/Products/CMFPlone/interfaces/siteroot.py\nindex 85df8e7c18..925ab9ae3a 100644\n--- a/Products/CMFPlone/interfaces/siteroot.py\n+++ b/Products/CMFPlone/interfaces/siteroot.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.siteroot\', \'Version 7.0\')\n+moved("plone.base.interfaces.siteroot", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/structure.py b/Products/CMFPlone/interfaces/structure.py\nindex dd4bb753ce..214f9655fc 100644\n--- a/Products/CMFPlone/interfaces/structure.py\n+++ b/Products/CMFPlone/interfaces/structure.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.structure\', \'Version 7.0\')\n+moved("plone.base.interfaces.structure", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/syndication.py b/Products/CMFPlone/interfaces/syndication.py\nindex e6a459d7a7..a194492a8b 100644\n--- a/Products/CMFPlone/interfaces/syndication.py\n+++ b/Products/CMFPlone/interfaces/syndication.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.syndication\', \'Version 7.0\')\n+moved("plone.base.interfaces.syndication", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/translationservice.py b/Products/CMFPlone/interfaces/translationservice.py\nindex c91a2ec402..1abd587a4f 100644\n--- a/Products/CMFPlone/interfaces/translationservice.py\n+++ b/Products/CMFPlone/interfaces/translationservice.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.interfaces.translationservice\', \'Version 7.0\')\n+moved("plone.base.interfaces.translationservice", "Version 7.0")\ndiff --git a/Products/CMFPlone/interfaces/workflow.py b/Products/CMFPlone/interfaces/workflow.py\nindex e056c93889..336834b602 100644\n--- a/Products/CMFPlone/interfaces/workflow.py\n+++ b/Products/CMFPlone/interfaces/workflow.py\n@@ -2,5 +2,4 @@\n \n \n class IWorkflowChain(IReadSequence):\n- """ an interface denoting the cmf workflow name sequence\n- """\n+ """an interface denoting the cmf workflow name sequence"""\ndiff --git a/Products/CMFPlone/log.py b/Products/CMFPlone/log.py\nindex 4b2df2ba85..aceffb1ad5 100644\n--- a/Products/CMFPlone/log.py\n+++ b/Products/CMFPlone/log.py\n@@ -7,23 +7,24 @@\n import logging\n \n \n-logger = logging.getLogger(\'Plone\')\n+logger = logging.getLogger("Plone")\n \n \n # generic log method\n-def log(message, summary=\'\', severity=logging.INFO):\n- logger.log(severity, \'%s \\n%s\', summary, message)\n+def log(message, summary="", severity=logging.INFO):\n+ logger.log(severity, "%s \\n%s", summary, message)\n \n \n # log message + exception info\n-def log_exc(message=\'\', summary=\'\', severity=logging.ERROR):\n- logger.log(severity, \'%s \\n%s\', summary, message, exc_info=True)\n+def log_exc(message="", summary="", severity=logging.ERROR):\n+ logger.log(severity, "%s \\n%s", summary, message, exc_info=True)\n \n \n # deprecration warning\n-@deprecate("Use a recommended deprecation method, see Plone Deprecation Guide: "\n- "https://docs.plone.org/develop/styleguide/deprecation.html "\n- "(will be removed in Plone 7.0)")\n-def log_deprecated(message, summary=\'Deprecation Warning\',\n- severity=logging.WARNING):\n- logger.log(severity, \'%s \\n%s\', summary, message)\n+@deprecate(\n+ "Use a recommended deprecation method, see Plone Deprecation Guide: "\n+ "https://docs.plone.org/develop/styleguide/deprecation.html "\n+ "(will be removed in Plone 7.0)"\n+)\n+def log_deprecated(message, summary="Deprecation Warning", severity=logging.WARNING):\n+ logger.log(severity, "%s \\n%s", summary, message)\ndiff --git a/Products/CMFPlone/patches/__init__.py b/Products/CMFPlone/patches/__init__.py\nindex 5adf744414..e8234dc395 100644\n--- a/Products/CMFPlone/patches/__init__.py\n+++ b/Products/CMFPlone/patches/__init__.py\n@@ -13,7 +13,7 @@\n \n # utf-8 encoded strings as well as Unicode\n \n-csrf.applyPatches() # CSRF attacks\n+csrf.applyPatches() # CSRF attacks\n \n from . import iso8601 # use `DateTime.ISO8601` for `DateTime.ISO`\n from . import speed # Various caching patches to improve speed\ndiff --git a/Products/CMFPlone/patches/addzmiplonesite.py b/Products/CMFPlone/patches/addzmiplonesite.py\nindex 922157ab20..a772ab71cd 100644\n--- a/Products/CMFPlone/patches/addzmiplonesite.py\n+++ b/Products/CMFPlone/patches/addzmiplonesite.py\n@@ -3,7 +3,7 @@\n \n # FIXME: This no longer works with the new ZMI\n \n-ADD_PLONE_SITE_HTML = \'\'\'\n+ADD_PLONE_SITE_HTML = """\n \n \n \n \n-\'\'\'\n+"""\n \n main = ObjectManager.manage_main\n orig = main.read()\n-pos = orig.find(\'\')\n+pos = orig.find("")\n \n # Add in our button html at the right position\n new = orig[:pos] + ADD_PLONE_SITE_HTML + orig[pos:]\ndiff --git a/Products/CMFPlone/patches/addzmisecuritywarning.py b/Products/CMFPlone/patches/addzmisecuritywarning.py\nindex edc8a821ab..fc7abe0ab9 100644\n--- a/Products/CMFPlone/patches/addzmisecuritywarning.py\n+++ b/Products/CMFPlone/patches/addzmisecuritywarning.py\n@@ -1,7 +1,7 @@\n from OFS.role import RoleManager\n \n \n-ADD_SECURITY_WARNING = \'\'\'\n+ADD_SECURITY_WARNING = """\n \n \n \n@@ -12,11 +12,11 @@\n Plone. More complex changes should be made using workflows where appropriate.
\n \n \n-\'\'\'\n+"""\n \n normal = RoleManager._normal_manage_access\n orig = normal.read()\n-pos = orig.find(\'\')\n+pos = orig.find("")\n \n # Add in our warning at the right position\n new = orig[:pos] + ADD_SECURITY_WARNING + orig[pos:]\ndiff --git a/Products/CMFPlone/patches/csrf.py b/Products/CMFPlone/patches/csrf.py\nindex fed69d0da3..881936c2f9 100644\n--- a/Products/CMFPlone/patches/csrf.py\n+++ b/Products/CMFPlone/patches/csrf.py\n@@ -7,12 +7,14 @@\n \n \n def applyPatches():\n- """ apply csrf-protection decorator to all relevant methods """\n+ """apply csrf-protection decorator to all relevant methods"""\n \n from Products.PlonePAS.tools.membership import MembershipTool as PMT\n+\n PMT.setPassword = patch(PMT.setPassword)\n \n from Products.CMFCore.MembershipTool import MembershipTool as MT\n+\n MT.setPassword = patch(MT.setPassword)\n MT.setRoleMapping = patch(MT.setRoleMapping)\n MT.deleteMemberArea = patch(MT.deleteMemberArea)\n@@ -21,6 +23,7 @@ def applyPatches():\n MT.deleteMembers = patch(MT.deleteMembers)\n \n from Products.CMFCore.MemberDataTool import MemberAdapter as MD\n+\n original_setProperties = MD.setProperties\n \n def setProperties(self, properties=None, REQUEST=None, **kw):\n@@ -30,17 +33,19 @@ def setProperties(self, properties=None, REQUEST=None, **kw):\n MD.setProperties = patch(setProperties)\n \n from Products.PlonePAS.tools.groupdata import GroupData\n+\n GroupData.addMember = patch(GroupData.addMember)\n GroupData.removeMember = patch(GroupData.removeMember)\n \n from Products.PlonePAS.tools.groups import GroupsTool\n+\n GroupsTool.addPrincipalToGroup = patch(GroupsTool.addPrincipalToGroup)\n- GroupsTool.removePrincipalFromGroup = patch(\n- GroupsTool.removePrincipalFromGroup)\n+ GroupsTool.removePrincipalFromGroup = patch(GroupsTool.removePrincipalFromGroup)\n \n from Products.PluggableAuthService.PluggableAuthService import (\n PluggableAuthService as PAS,\n )\n+\n PAS.userFolderAddUser = patch(PAS.userFolderAddUser)\n PAS.userFolderEditUser = patch(PAS.userFolderEditUser)\n PAS.userFolderDelUsers = patch(PAS.userFolderDelUsers)\ndiff --git a/Products/CMFPlone/patches/dateIndexPatch.py b/Products/CMFPlone/patches/dateIndexPatch.py\nindex f4b5b0a66d..31aad65433 100644\n--- a/Products/CMFPlone/patches/dateIndexPatch.py\n+++ b/Products/CMFPlone/patches/dateIndexPatch.py\n@@ -14,6 +14,7 @@ def _convert(self, value, default=None):\n except OverflowError:\n return self.__old_convert(maxDate, default)\n \n+\n DateIndex.__old_convert = DateIndex._convert\n DateIndex._convert = _convert\n \n@@ -24,5 +25,6 @@ def _convertDateTime(self, value):\n except OverflowError:\n return self.__old_convertDateTime(maxDate)\n \n+\n DateRangeIndex.__old_convertDateTime = DateRangeIndex._convertDateTime\n DateRangeIndex._convertDateTime = _convertDateTime\ndiff --git a/Products/CMFPlone/patches/gtbn.py b/Products/CMFPlone/patches/gtbn.py\nindex f5855776ae..efb5046b27 100644\n--- a/Products/CMFPlone/patches/gtbn.py\n+++ b/Products/CMFPlone/patches/gtbn.py\n@@ -8,22 +8,26 @@\n \n \n def rewrap_in_request_container(obj, context=None):\n- \'\'\'Fix an object\'s acquisition wrapper to be able to acquire the REQUEST.\'\'\'\n- request = getattr(context, \'REQUEST\', None) or getRequest()\n+ """Fix an object\'s acquisition wrapper to be able to acquire the REQUEST."""\n+ request = getattr(context, "REQUEST", None) or getRequest()\n if IAcquirer.providedBy(obj) and request is not None:\n chain = []\n parent = obj\n while 1:\n chain.append(parent)\n parent = aq_parent(aq_inner(parent))\n- if parent in chain or parent is None or isinstance(\n- parent, RequestContainer):\n+ if (\n+ parent in chain\n+ or parent is None\n+ or isinstance(parent, RequestContainer)\n+ ):\n break\n obj = RequestContainer(REQUEST=request)\n for ob in reversed(chain):\n obj = aq_base(ob).__of__(obj)\n return obj\n \n+\n # Check return value of getToolByName\n # this used to be step 5 in earlypatches, but was moved to avoid\n # circular imports.\n@@ -51,13 +55,16 @@ def check_getToolByName(obj, name, default=_marker):\n raise TypeError("Object found is not a portal tool (%s)" % (name,))\n return result\n """\n-if \'_marker\' not in utils.getToolByName.__globals__:\n- raise Exception("This Version of Products.CMFPlone is not compatible "\n- "with Products.PloneHotfix20121106, the fixes are "\n- "included already in Products.CMFPlone, please remove "\n- "the hotfix")\n+if "_marker" not in utils.getToolByName.__globals__:\n+ raise Exception(\n+ "This Version of Products.CMFPlone is not compatible "\n+ "with Products.PloneHotfix20121106, the fixes are "\n+ "included already in Products.CMFPlone, please remove "\n+ "the hotfix"\n+ )\n utils.getToolByName.__globals__[\n- \'rewrap_in_request_container\'] = rewrap_in_request_container\n+ "rewrap_in_request_container"\n+] = rewrap_in_request_container\n exec(code, utils.getToolByName.__globals__)\n utils._getToolByName.__code__ = utils.getToolByName.__code__\n utils.getToolByName.__code__ = utils.check_getToolByName.__code__\ndiff --git a/Products/CMFPlone/patches/iso8601.py b/Products/CMFPlone/patches/iso8601.py\nindex 785b255d10..f616b67211 100644\n--- a/Products/CMFPlone/patches/iso8601.py\n+++ b/Products/CMFPlone/patches/iso8601.py\n@@ -3,9 +3,9 @@\n \n \n def ISO(self):\n- """ return ISO8601 instead of ISO format, i.e. including the time zone.\n- the latter shouldn\'t be used anymore. please see\n- http://dev.plone.org/plone/ticket/10140 for more info """\n+ """return ISO8601 instead of ISO format, i.e. including the time zone.\n+ the latter shouldn\'t be used anymore. please see\n+ http://dev.plone.org/plone/ticket/10140 for more info"""\n # Disable the warning until we fixed all of Plone Core.\n # warn(\'Calls to `DateTime.ISO()` should be replaced with \'\n # \'`DateTime.ISO8601()` to avoid implicit changes to GMT in \'\ndiff --git a/Products/CMFPlone/patches/publishing.py b/Products/CMFPlone/patches/publishing.py\nindex 5c86d0c274..a0779cf983 100644\n--- a/Products/CMFPlone/patches/publishing.py\n+++ b/Products/CMFPlone/patches/publishing.py\n@@ -19,31 +19,31 @@ def delete_method_docstring(klass, method_name):\n \n \n klasses = (\n-# Node,\n-# Document,\n+ # Node,\n+ # Document,\n PloneSite,\n Item,\n Container,\n )\n methods = (\n- \'EffectiveDate\',\n- \'ExpirationDate\',\n- \'getAttributes\',\n- \'getChildNodes\',\n- \'getFirstChild\',\n- \'getLastChild\',\n- \'getLayout\',\n- \'getNextSibling\',\n- \'getNodeName\',\n- \'getNodeType\',\n- \'getNodeValue\',\n- \'getOwnerDocument\',\n- \'getParentNode\',\n- \'getPhysicalPath\',\n- \'getPreviousSibling\',\n- \'getTagName\',\n- \'hasChildNodes\',\n- \'Type\'\n+ "EffectiveDate",\n+ "ExpirationDate",\n+ "getAttributes",\n+ "getChildNodes",\n+ "getFirstChild",\n+ "getLastChild",\n+ "getLayout",\n+ "getNextSibling",\n+ "getNodeName",\n+ "getNodeType",\n+ "getNodeValue",\n+ "getOwnerDocument",\n+ "getParentNode",\n+ "getPhysicalPath",\n+ "getPreviousSibling",\n+ "getTagName",\n+ "hasChildNodes",\n+ "Type",\n )\n \n for klass in klasses:\n@@ -51,15 +51,15 @@ def delete_method_docstring(klass, method_name):\n delete_method_docstring(klass, method_name)\n \n property_methods = (\n- \'getProperty\',\n- \'propertyValues\',\n- \'propertyItems\',\n- \'propertyMap\',\n- \'hasProperty\',\n- \'getPropertyType\',\n- \'propertyIds\',\n- \'propertyLabel\',\n- \'propertyDescription\'\n+ "getProperty",\n+ "propertyValues",\n+ "propertyItems",\n+ "propertyMap",\n+ "hasProperty",\n+ "getPropertyType",\n+ "propertyIds",\n+ "propertyLabel",\n+ "propertyDescription",\n )\n \n for method_name in property_methods:\ndiff --git a/Products/CMFPlone/patches/sendmail.py b/Products/CMFPlone/patches/sendmail.py\nindex 5d048674f0..126d45aaf0 100644\n--- a/Products/CMFPlone/patches/sendmail.py\n+++ b/Products/CMFPlone/patches/sendmail.py\n@@ -32,22 +32,23 @@ def _catch(*args, **kwargs):\n \n def applyPatches():\n from zope.sendmail.mailer import SMTPMailer\n- old_mailer = getattr(SMTPMailer, \'vote\', None) is None\n+\n+ old_mailer = getattr(SMTPMailer, "vote", None) is None\n if old_mailer:\n SMTPMailer.send = catchAllExceptions(SMTPMailer.send)\n \n \n def new_init(\n- self,\n- hostname=\'localhost\',\n- port=25,\n- username=None,\n- password=None,\n- no_tls=False,\n- force_tls=False):\n-\n+ self,\n+ hostname="localhost",\n+ port=25,\n+ username=None,\n+ password=None,\n+ no_tls=False,\n+ force_tls=False,\n+):\n registry = getUtility(IRegistry)\n- mail_settings = registry.forInterface(IMailSchema, prefix=\'plone\')\n+ mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n self.hostname = mail_settings.smtp_host\n self.port = mail_settings.smtp_port\n self.username = mail_settings.smtp_userid\ndiff --git a/Products/CMFPlone/patches/speed.py b/Products/CMFPlone/patches/speed.py\nindex 17297da87b..23fb7566a8 100644\n--- a/Products/CMFPlone/patches/speed.py\n+++ b/Products/CMFPlone/patches/speed.py\n@@ -3,20 +3,24 @@\n \n \n # Remember the installed products and packages (unless running tests)\n-if not \'ZOPETESTCASE\' in environ:\n+if not "ZOPETESTCASE" in environ:\n from App import FactoryDispatcher\n- FactoryDispatcher._product_packages = \\\n- forever.memoize(FactoryDispatcher._product_packages)\n+\n+ FactoryDispatcher._product_packages = forever.memoize(\n+ FactoryDispatcher._product_packages\n+ )\n \n \n # Avoid unneeded line breaks in TAL output, by effectively disabling the\n # internal beautified wrapping inside tags\n def wrap_init(func):\n def new_init(*args, **kwargs):\n- kwargs[\'wrap\'] = kwargs.get(\'wrap\', 1023)\n+ kwargs["wrap"] = kwargs.get("wrap", 1023)\n func(*args, **kwargs)\n+\n return new_init\n \n+\n from zope.tal.talinterpreter import TALInterpreter\n \n \n@@ -27,11 +31,12 @@ def new_init(*args, **kwargs):\n # that opaque items are completely unused inside Plone\n def opaqueItems(self):\n """\n- Return opaque items (subelements that are contained\n- using something that is not an ObjectManager).\n+ Return opaque items (subelements that are contained\n+ using something that is not an ObjectManager).\n """\n return ()\n \n+\n from Products.CMFCore.CMFCatalogAware import OpaqueItemManager\n \n \ndiff --git a/Products/CMFPlone/patches/templatecookcheck.py b/Products/CMFPlone/patches/templatecookcheck.py\nindex e9255b1dad..7fe29f6ca6 100644\n--- a/Products/CMFPlone/patches/templatecookcheck.py\n+++ b/Products/CMFPlone/patches/templatecookcheck.py\n@@ -24,8 +24,11 @@ def _cook_check(self):\n self.pt_edit(text, type_)\n assert self._v_cooked\n if self._v_errors:\n- logging.error(\'PageTemplateFile: Error in template %s: %s\',\n- self.filename, \'\\n\'.join(self._v_errors))\n+ logging.error(\n+ "PageTemplateFile: Error in template %s: %s",\n+ self.filename,\n+ "\\n".join(self._v_errors),\n+ )\n return\n self._v_last_read = mtime\n \ndiff --git a/Products/CMFPlone/patches/unicodehacks.py b/Products/CMFPlone/patches/unicodehacks.py\nindex c6ebf7499f..abb5e15a08 100644\n--- a/Products/CMFPlone/patches/unicodehacks.py\n+++ b/Products/CMFPlone/patches/unicodehacks.py\n@@ -1,15 +1,15 @@\n def _unicode_replace(structure):\n if isinstance(structure, bytes):\n- return structure.decode(\'utf-8\', \'replace\')\n+ return structure.decode("utf-8", "replace")\n return str(structure)\n \n \n def _nulljoin(valuelist):\n try:\n- return \'\'.join(valuelist)\n+ return "".join(valuelist)\n except UnicodeDecodeError:\n pass\n- return \'\'.join([_unicode_replace(value) for value in valuelist])\n+ return "".join([_unicode_replace(value) for value in valuelist])\n \n \n def new__call__(self, econtext):\n@@ -17,13 +17,12 @@ def new__call__(self, econtext):\n return self._expr % tuple(var(econtext) for var in self._vars)\n except UnicodeDecodeError:\n pass\n- return self._expr % tuple(_unicode_replace(var(econtext))\n- for var in self._vars)\n+ return self._expr % tuple(_unicode_replace(var(econtext)) for var in self._vars)\n \n \n class FasterStringIO(list):\n- """Append-only version of StringIO.\n- """\n+ """Append-only version of StringIO."""\n+\n write = list.append\n \n def __init__(self, value=None):\n@@ -33,6 +32,6 @@ def __init__(self, value=None):\n \n def getvalue(self):\n try:\n- return \'\'.join(self)\n+ return "".join(self)\n except UnicodeDecodeError:\n- return \'\'.join([_unicode_replace(value) for value in self])\n+ return "".join([_unicode_replace(value) for value in self])\ndiff --git a/Products/CMFPlone/patches/z3c_form.py b/Products/CMFPlone/patches/z3c_form.py\nindex c65b18dc66..2f859071c2 100644\n--- a/Products/CMFPlone/patches/z3c_form.py\n+++ b/Products/CMFPlone/patches/z3c_form.py\n@@ -7,7 +7,7 @@\n # Usually all forms are only for POST, and we disallow filling it with GET\n # data. This works the way around too: allow prefilling from a POST request\n # when the form only handles GET. But that is unlikely.\n-ALLOW_PREFILL = \'allow_prefill_from_GET_request\'\n+ALLOW_PREFILL = "allow_prefill_from_GET_request"\n \n \n def _wrap_update(update):\n@@ -20,12 +20,14 @@ def _wrapped(self):\n # all widgets. But it seems an international sport to override the\n # update or updateWidgets method of the base z3c form, which makes it\n # hard to fix all occurrences by one check on the form.\n- if not self.ignoreRequest and getattr(self.form, \'ignoreRequest\', False):\n+ if not self.ignoreRequest and getattr(self.form, "ignoreRequest", False):\n self.ignoreRequest = True\n # If we are not already ignoring the request, check the request method.\n- if (not self.ignoreRequest\n- and hasattr(self.form, \'method\')\n- and hasattr(self.request, \'REQUEST_METHOD\')):\n+ if (\n+ not self.ignoreRequest\n+ and hasattr(self.form, "method")\n+ and hasattr(self.request, "REQUEST_METHOD")\n+ ):\n if self.request.REQUEST_METHOD.lower() != self.form.method.lower():\n # This is an unexpected request method.\n # For special cases we allow a form to bail out.\n@@ -33,9 +35,9 @@ def _wrapped(self):\n self.ignoreRequest = True\n self.form.ignoreRequest = True\n # If we are not already ignoring the request, check the referer.\n- if not self.ignoreRequest and hasattr(self.request, \'environ\'):\n+ if not self.ignoreRequest and hasattr(self.request, "environ"):\n env = self.request.environ\n- referrer = env.get(\'HTTP_REFERER\', env.get(\'HTTP_REFERRER\'))\n+ referrer = env.get("HTTP_REFERER", env.get("HTTP_REFERRER"))\n if referrer:\n req_url_parsed = urlparse(self.request.URL)\n referrer_parsed = urlparse(referrer)\n@@ -44,6 +46,7 @@ def _wrapped(self):\n self.ignoreRequest = True\n self.form.ignoreRequest = True\n return update(self)\n+\n return _wrapped\n \n \ndiff --git a/Products/CMFPlone/permissions.py b/Products/CMFPlone/permissions.py\nindex 27b024b1de..9cae28c787 100644\n--- a/Products/CMFPlone/permissions.py\n+++ b/Products/CMFPlone/permissions.py\n@@ -1,4 +1,4 @@\n from zope.deprecation import moved\n \n \n-moved(\'plone.base.permissions\', \'Version 7.0\')\n+moved("plone.base.permissions", "Version 7.0")\ndiff --git a/Products/CMFPlone/relationhelper.py b/Products/CMFPlone/relationhelper.py\nindex b9cbd3e568..5976b49f71 100644\n--- a/Products/CMFPlone/relationhelper.py\n+++ b/Products/CMFPlone/relationhelper.py\n@@ -40,7 +40,7 @@\n \n logger = logging.getLogger(__name__)\n \n-RELATIONS_KEY = \'ALL_REFERENCES\'\n+RELATIONS_KEY = "ALL_REFERENCES"\n \n \n def rebuild_relations(context=None, flush_and_rebuild_intids=False):\n@@ -62,8 +62,8 @@ def get_relations_stats():\n try:\n rel = relation_catalog.resolveRelationToken(token)\n except ObjectMissingError:\n- broken[\'Object is missing\'] += 1\n- logger.info(f\'Token {token} has no object.\')\n+ broken["Object is missing"] += 1\n+ logger.info(f"Token {token} has no object.")\n continue\n \n if rel.isBroken():\n@@ -85,35 +85,38 @@ def get_all_relations():\n try:\n rel = relation_catalog.resolveRelationToken(token)\n except ObjectMissingError:\n- logger.info(f\'Token {token} has no object.\')\n+ logger.info(f"Token {token} has no object.")\n continue\n \n if rel.from_object and rel.to_object:\n try:\n- results.append({\n- \'from_uuid\': rel.from_object.UID(),\n- \'to_uuid\': rel.to_object.UID(),\n- \'from_attribute\': rel.from_attribute,\n- })\n+ results.append(\n+ {\n+ "from_uuid": rel.from_object.UID(),\n+ "to_uuid": rel.to_object.UID(),\n+ "from_attribute": rel.from_attribute,\n+ }\n+ )\n info[rel.from_attribute] += 1\n except AttributeError as ex:\n- logger.info(f\'Something went wrong while storing {rel}: \\n {ex}\')\n+ logger.info(f"Something went wrong while storing {rel}: \\n {ex}")\n else:\n- logger.info(f\'Dropping relation {rel.from_attribute} from {rel.from_object} to {rel.to_object}\')\n- msg = \'\'\n+ logger.info(\n+ f"Dropping relation {rel.from_attribute} from {rel.from_object} to {rel.to_object}"\n+ )\n+ msg = ""\n for key, value in info.items():\n- msg += f\'{key}: {value}\\n\'\n- logger.info(f\'\\nFound the following relations:\\n{msg}\')\n+ msg += f"{key}: {value}\\n"\n+ logger.info(f"\\nFound the following relations:\\n{msg}")\n return results\n \n \n def store_relations(context=None):\n- """Store all relations in a annotation on the portal.\n- """\n+ """Store all relations in a annotation on the portal."""\n all_relations = get_all_relations()\n portal = getSite()\n IAnnotations(portal)[RELATIONS_KEY] = all_relations\n- logger.info(f\'Stored {len(all_relations)} relations on the portal\')\n+ logger.info(f"Stored {len(all_relations)} relations on the portal")\n \n \n def purge_relations(context=None):\n@@ -123,17 +126,16 @@ def purge_relations(context=None):\n """\n rel_catalog = getUtility(ICatalog)\n rel_catalog.clear()\n- logger.info(\'Purged zc.relation catalog\')\n+ logger.info("Purged zc.relation catalog")\n \n \n def restore_relations(context=None, all_relations=None):\n- """Restore relations from a annotation on the portal.\n- """\n+ """Restore relations from a annotation on the portal."""\n \n portal = getSite()\n if all_relations is None:\n all_relations = IAnnotations(portal)[RELATIONS_KEY]\n- logger.info(f\'Loaded {len(all_relations)} relations to restore\')\n+ logger.info(f"Loaded {len(all_relations)} relations to restore")\n update_linkintegrity = set()\n modified_items = set()\n modified_relation_lists = defaultdict(list)\n@@ -148,24 +150,24 @@ def restore_relations(context=None, all_relations=None):\n unique_relations.append(rel)\n seen_add(hashable)\n else:\n- logger.info(f\'Dropping duplicate: {hashable}\')\n+ logger.info(f"Dropping duplicate: {hashable}")\n \n if len(unique_relations) < len(all_relations):\n- logger.info(f\'Dropping {len(all_relations) - len(unique_relations)} duplicates\')\n+ logger.info(f"Dropping {len(all_relations) - len(unique_relations)} duplicates")\n all_relations = unique_relations\n \n intids = getUtility(IIntIds)\n for index, item in enumerate(all_relations, start=1):\n if not index % 500:\n- logger.info(f\'Restored {index} of {len(all_relations)} relations...\')\n+ logger.info(f"Restored {index} of {len(all_relations)} relations...")\n \n try:\n- source_obj = uuidToObject(item[\'from_uuid\'])\n+ source_obj = uuidToObject(item["from_uuid"])\n except KeyError:\n # brain exists but no object\n source_obj = None\n try:\n- target_obj = uuidToObject(item[\'to_uuid\'])\n+ target_obj = uuidToObject(item["to_uuid"])\n except KeyError:\n # brain exists but no object\n target_obj = None\n@@ -179,23 +181,23 @@ def restore_relations(context=None, all_relations=None):\n continue\n \n if not IDexterityContent.providedBy(source_obj):\n- logger.info(f\'{source_obj} is no dexterity content\')\n+ logger.info(f"{source_obj} is no dexterity content")\n continue\n \n if not IDexterityContent.providedBy(target_obj):\n- logger.info(f\'{target_obj} is no dexterity content\')\n+ logger.info(f"{target_obj} is no dexterity content")\n continue\n \n- from_attribute = item[\'from_attribute\']\n+ from_attribute = item["from_attribute"]\n try:\n to_id = intids.getId(target_obj)\n except KeyError as e:\n- logger.warning(f\'No intid for {target_obj}\')\n+ logger.warning(f"No intid for {target_obj}")\n continue\n \n if from_attribute == referencedRelationship:\n # Ignore linkintegrity for now. We\'ll rebuilt it at the end!\n- update_linkintegrity.add(item[\'from_uuid\'])\n+ update_linkintegrity.add(item["from_uuid"])\n continue\n \n if HAS_ITERATE and from_attribute == ITERATE_RELATION_NAME:\n@@ -204,10 +206,12 @@ def restore_relations(context=None, all_relations=None):\n event._setRelation(source_obj, ITERATE_RELATION_NAME, relation)\n continue\n \n- field_and_schema = get_field_and_schema_for_fieldname(from_attribute, source_obj.portal_type)\n+ field_and_schema = get_field_and_schema_for_fieldname(\n+ from_attribute, source_obj.portal_type\n+ )\n if field_and_schema is None:\n # the from_attribute is no field\n- logger.info(f\'No field. Setting relation: {item}\')\n+ logger.info(f"No field. Setting relation: {item}")\n event._setRelation(source_obj, from_attribute, RelationValue(to_id))\n continue\n \n@@ -215,8 +219,10 @@ def restore_relations(context=None, all_relations=None):\n relation = RelationValue(to_id)\n \n if isinstance(field, RelationList):\n- logger.info(f\'Add relation to relationslist {from_attribute} from {source_obj.absolute_url()} to {target_obj.absolute_url()}\')\n- if item[\'from_uuid\'] in modified_relation_lists.get(from_attribute, []):\n+ logger.info(\n+ f"Add relation to relationslist {from_attribute} from {source_obj.absolute_url()} to {target_obj.absolute_url()}"\n+ )\n+ if item["from_uuid"] in modified_relation_lists.get(from_attribute, []):\n # Do not purge relations\n existing_relations = getattr(source_obj, from_attribute, [])\n else:\n@@ -224,25 +230,29 @@ def restore_relations(context=None, all_relations=None):\n existing_relations = []\n existing_relations.append(relation)\n setattr(source_obj, from_attribute, existing_relations)\n- modified_items.add(item[\'from_uuid\'])\n- modified_relation_lists[from_attribute].append(item[\'from_uuid\'])\n+ modified_items.add(item["from_uuid"])\n+ modified_relation_lists[from_attribute].append(item["from_uuid"])\n continue\n \n elif isinstance(field, (Relation, RelationChoice)):\n- logger.info(f\'Add relation {from_attribute} from {source_obj.absolute_url()} to {target_obj.absolute_url()}\')\n+ logger.info(\n+ f"Add relation {from_attribute} from {source_obj.absolute_url()} to {target_obj.absolute_url()}"\n+ )\n setattr(source_obj, from_attribute, relation)\n- modified_items.add(item[\'from_uuid\'])\n+ modified_items.add(item["from_uuid"])\n continue\n \n else:\n # we should never end up here!\n- logger.warn(f\'Unexpected relation {from_attribute} from {source_obj.absolute_url()} to {target_obj.absolute_url()}\')\n+ logger.warn(\n+ f"Unexpected relation {from_attribute} from {source_obj.absolute_url()} to {target_obj.absolute_url()}"\n+ )\n \n update_linkintegrity = set(update_linkintegrity)\n- logger.info(f\'Updating linkintegrity for {len(update_linkintegrity)} items\')\n+ logger.info(f"Updating linkintegrity for {len(update_linkintegrity)} items")\n for uuid in sorted(update_linkintegrity):\n modifiedContent(uuidToObject(uuid), None)\n- logger.info(f\'Updating relations for {len(modified_items)} items\')\n+ logger.info(f"Updating relations for {len(modified_items)} items")\n for uuid in sorted(modified_items):\n obj = uuidToObject(uuid)\n # updateRelations from z3c.relationfield does not properly update relations in behaviors\n@@ -255,7 +265,7 @@ def restore_relations(context=None, all_relations=None):\n # purge annotation from portal if they exist\n if RELATIONS_KEY in IAnnotations(portal):\n del IAnnotations(portal)[RELATIONS_KEY]\n- logger.info(\'Done!\')\n+ logger.info("Done!")\n \n \n def get_intid(obj):\n@@ -272,10 +282,9 @@ def get_intid(obj):\n \n \n def get_field_and_schema_for_fieldname(field_id, portal_type):\n- """Get field and its schema from a portal_type.\n- """\n+ """Get field and its schema from a portal_type."""\n # Turn form.widgets.IDublinCore.title into title\n- field_id = field_id.split(\'.\')[-1]\n+ field_id = field_id.split(".")[-1]\n for schema in iterSchemataForType(portal_type):\n field = schema.get(field_id, None)\n if field is not None:\n@@ -284,8 +293,10 @@ def get_field_and_schema_for_fieldname(field_id, portal_type):\n \n def cleanup_intids(context=None):\n intids = getUtility(IIntIds)\n- all_refs = [f\'{i.object.__class__.__module__}.{i.object.__class__.__name__}\'\n- for i in intids.refs.values()]\n+ all_refs = [\n+ f"{i.object.__class__.__module__}.{i.object.__class__.__name__}"\n+ for i in intids.refs.values()\n+ ]\n logger.info(Counter(all_refs))\n \n count = 0\n@@ -293,34 +304,34 @@ def cleanup_intids(context=None):\n for ref in refs:\n intids.unregister(ref)\n count += 1\n- logger.info(f\'Removed all {count} RelationValues from IntId-tool\')\n+ logger.info(f"Removed all {count} RelationValues from IntId-tool")\n \n count = 0\n for ref in intids.refs.values():\n- if \'broken\' in repr(ref.object):\n+ if "broken" in repr(ref.object):\n intids.unregister(ref)\n- logger.info(f\'Removed {count} broken refs from IntId-tool\')\n- all_refs = [\'{i.object.__class__.__module__}.{i.object.__class__.__name__}\'\n- for i in intids.refs.values()]\n+ logger.info(f"Removed {count} broken refs from IntId-tool")\n+ all_refs = [\n+ "{i.object.__class__.__module__}.{i.object.__class__.__name__}"\n+ for i in intids.refs.values()\n+ ]\n logger.info(Counter(all_refs))\n \n \n def flush_intids():\n- """ Flush all intids\n- """\n+ """Flush all intids"""\n intids = getUtility(IIntIds)\n intids.ids = intids.family.OI.BTree()\n intids.refs = intids.family.IO.BTree()\n \n \n def rebuild_intids():\n- """ Create new intids\n- """\n+ """Create new intids"""\n+\n def add_to_intids(obj, path):\n if IContentish.providedBy(obj):\n- logger.info(f\'Added {obj} at {path} to intid\')\n+ logger.info(f"Added {obj} at {path} to intid")\n addIntIdSubscriber(obj, None)\n+\n portal = getSite()\n- portal.ZopeFindAndApply(portal,\n- search_sub=True,\n- apply_func=add_to_intids)\n+ portal.ZopeFindAndApply(portal, search_sub=True, apply_func=add_to_intids)\ndiff --git a/Products/CMFPlone/resources/browser/resource.py b/Products/CMFPlone/resources/browser/resource.py\nindex 07369c6176..9e5808da57 100644\n--- a/Products/CMFPlone/resources/browser/resource.py\n+++ b/Products/CMFPlone/resources/browser/resource.py\n@@ -55,17 +55,17 @@ def _user_local_roles(self, site):\n \n def _cache_attr_name(self, site):\n hashtool = hashlib.sha256()\n- hashtool.update(self.__class__.__name__.encode(\'utf8\'))\n- hashtool.update(site.absolute_url().encode(\'utf8\'))\n+ hashtool.update(self.__class__.__name__.encode("utf8"))\n+ hashtool.update(site.absolute_url().encode("utf8"))\n e_bundles, d_bundles = self._request_bundles()\n for bundle in e_bundles | d_bundles:\n- hashtool.update(bundle.encode(\'utf8\'))\n+ hashtool.update(bundle.encode("utf8"))\n hashtool.update(self._user_local_roles(site).encode("utf8"))\n if not getattr(self, "registry", None):\n self.registry = getUtility(IRegistry)\n mtime = getattr(self.registry, _RESOURCE_REGISTRY_MTIME, None)\n if mtime is not None:\n- hashtool.update(str(mtime).encode(\'utf8\'))\n+ hashtool.update(str(mtime).encode("utf8"))\n return f"_v_rendered_cache_{hashtool.hexdigest()}"\n \n @property\n@@ -151,17 +151,15 @@ def check_dependencies(bundle_name, depends, bundles):\n # gracefully rewrite old bundle names\n graceful_depends = GRACEFUL_DEPENDENCY_REWRITE[name]\n logger.error(\n- msg\n- + f"Bundle dependency graceful rewritten to \'{graceful_depends}\' "\n- + "Fallback will be removed in Plone 7."\n- )\n+ msg\n+ + f"Bundle dependency graceful rewritten to \'{graceful_depends}\' "\n+ + "Fallback will be removed in Plone 7."\n+ )\n valid_dependencies.append(graceful_depends)\n continue\n \n # if the dependency does not exist, skip the bundle\n- logger.error(\n- msg + "Bundle ignored - This may break your site!"\n- )\n+ logger.error(msg + "Bundle ignored - This may break your site!")\n return "__broken__"\n \n return valid_dependencies\n@@ -194,7 +192,7 @@ def check_dependencies(bundle_name, depends, bundles):\n async_=record.load_async or None,\n defer=record.load_defer or None,\n integrity=not external,\n- **{\'data-bundle\': name},\n+ **{"data-bundle": name},\n )\n if record.csscompilation:\n depends = check_dependencies(name, record.depends, css_names)\n@@ -214,7 +212,7 @@ def check_dependencies(bundle_name, depends, bundles):\n url=record.csscompilation if external else None,\n media="all",\n rel="stylesheet",\n- **{\'data-bundle\': name},\n+ **{"data-bundle": name},\n )\n \n # Collect theme data\ndiff --git a/Products/CMFPlone/setuphandlers.py b/Products/CMFPlone/setuphandlers.py\nindex 0f97284c92..ba9cead29d 100644\n--- a/Products/CMFPlone/setuphandlers.py\n+++ b/Products/CMFPlone/setuphandlers.py\n@@ -18,11 +18,12 @@\n \n \n def addCacheHandlers(portal):\n- """ Add RAM and AcceleratedHTTP cache handlers """\n- mgrs = [(AcceleratedHTTPCacheManager, \'HTTPCache\'),\n- (RAMCacheManager, \'RAMCache\'),\n- (RAMCacheManager, \'ResourceRegistryCache\'),\n- ]\n+ """Add RAM and AcceleratedHTTP cache handlers"""\n+ mgrs = [\n+ (AcceleratedHTTPCacheManager, "HTTPCache"),\n+ (RAMCacheManager, "RAMCache"),\n+ (RAMCacheManager, "ResourceRegistryCache"),\n+ ]\n for mgr_class, mgr_id in mgrs:\n existing = portal.get(mgr_id, None)\n if existing is None:\n@@ -38,7 +39,7 @@ def purgeProfileVersions(portal):\n """\n Purge profile dependency versions.\n """\n- setup = getToolByName(portal, \'portal_setup\')\n+ setup = getToolByName(portal, "portal_setup")\n setup._profile_upgrade_versions = {}\n \n \n@@ -48,48 +49,48 @@ def setProfileVersion(portal):\n """\n mt = queryUtility(IMigrationTool)\n mt.setInstanceVersion(mt.getFileSystemVersion())\n- setup = getToolByName(portal, \'portal_setup\')\n+ setup = getToolByName(portal, "portal_setup")\n version = setup.getVersionForProfile(_DEFAULT_PROFILE)\n setup.setLastVersionForProfile(_DEFAULT_PROFILE, version)\n \n \n def assignTitles(portal):\n titles = {\n- \'acl_users\': \'User / Group storage and authentication settings\',\n- \'caching_policy_manager\': \'Settings related to proxy caching\',\n- \'content_type_registry\': \'MIME type settings\',\n- \'error_log\': \'Error and exceptions log viewer\',\n- \'MailHost\': \'Mail server settings for outgoing mail\',\n- \'mimetypes_registry\': \'MIME types recognized by Plone\',\n- \'plone_utils\': \'Various utility methods\',\n- \'portal_actions\': \'Contains custom tabs and buttons\',\n- \'portal_calendar\': \'Controls how events are shown\',\n- \'portal_catalog\': \'Indexes all content in the site\',\n- \'portal_controlpanel\': \'Registry of control panel screen\',\n- \'portal_diff\': \'Settings for content version comparisions\',\n- \'portal_groupdata\': \'Handles properties on groups\',\n- \'portal_groups\': \'Handles group related functionality\',\n- \'portal_languages\': \'Language specific settings\',\n- \'portal_membership\': \'Handles membership policies\',\n- \'portal_memberdata\': \'Handles the available properties on members\',\n- \'portal_migration\': \'Upgrades to newer Plone versions\',\n- \'portal_password_reset\': \'Handles password retention policy\',\n- \'portal_properties\': \'General settings registry\',\n- \'portal_registration\': \'Handles registration of new users\',\n- \'portal_setup\': \'Add-on and configuration management\',\n- \'portal_skins\': \'Controls skin behaviour (search order etc)\',\n- \'portal_transforms\': \'Handles data conversion between MIME types\',\n- \'portal_types\': \'Controls the available content types in your portal\',\n- \'portal_url\': \'Methods to anchor you to the root of your Plone site\',\n- \'portal_view_customizations\': \'Template customizations\',\n- \'portal_workflow\': \'Contains workflow definitions for your portal\',\n- \'reference_catalog\': \'Catalog of content references\',\n- \'translation_service\': \'Provides access to the translation machinery\',\n+ "acl_users": "User / Group storage and authentication settings",\n+ "caching_policy_manager": "Settings related to proxy caching",\n+ "content_type_registry": "MIME type settings",\n+ "error_log": "Error and exceptions log viewer",\n+ "MailHost": "Mail server settings for outgoing mail",\n+ "mimetypes_registry": "MIME types recognized by Plone",\n+ "plone_utils": "Various utility methods",\n+ "portal_actions": "Contains custom tabs and buttons",\n+ "portal_calendar": "Controls how events are shown",\n+ "portal_catalog": "Indexes all content in the site",\n+ "portal_controlpanel": "Registry of control panel screen",\n+ "portal_diff": "Settings for content version comparisions",\n+ "portal_groupdata": "Handles properties on groups",\n+ "portal_groups": "Handles group related functionality",\n+ "portal_languages": "Language specific settings",\n+ "portal_membership": "Handles membership policies",\n+ "portal_memberdata": "Handles the available properties on members",\n+ "portal_migration": "Upgrades to newer Plone versions",\n+ "portal_password_reset": "Handles password retention policy",\n+ "portal_properties": "General settings registry",\n+ "portal_registration": "Handles registration of new users",\n+ "portal_setup": "Add-on and configuration management",\n+ "portal_skins": "Controls skin behaviour (search order etc)",\n+ "portal_transforms": "Handles data conversion between MIME types",\n+ "portal_types": "Controls the available content types in your portal",\n+ "portal_url": "Methods to anchor you to the root of your Plone site",\n+ "portal_view_customizations": "Template customizations",\n+ "portal_workflow": "Contains workflow definitions for your portal",\n+ "reference_catalog": "Catalog of content references",\n+ "translation_service": "Provides access to the translation machinery",\n }\n for oid, obj in portal.items():\n title = titles.get(oid, None)\n if title:\n- setattr(aq_base(obj), \'title\', title)\n+ setattr(aq_base(obj), "title", title)\n \n \n def dummy_import_step(context):\n@@ -135,8 +136,7 @@ def importFinalSteps(context):\n \n # Install our dependencies\n st = getToolByName(site, "portal_setup")\n- st.runAllImportStepsFromProfile(\n- "profile-Products.CMFPlone:dependencies")\n+ st.runAllImportStepsFromProfile("profile-Products.CMFPlone:dependencies")\n \n assignTitles(site)\n replace_local_role_manager(site)\n@@ -166,10 +166,7 @@ def set_zsqlmethods_permissions(site):\n import Products.ZSQLMethods # noqa\n except ImportError:\n return\n- site.manage_permission(\n- \'Use Database Methods\',\n- [\'Site Administrator\'],\n- False)\n+ site.manage_permission("Use Database Methods", ["Site Administrator"], False)\n \n \n def updateWorkflowRoleMappings(context):\n@@ -179,18 +176,17 @@ def updateWorkflowRoleMappings(context):\n properly.\n """\n # Only run step if a flag file is present\n- if context.readDataFile(\'plone-update-workflow-rolemap.txt\') is None:\n+ if context.readDataFile("plone-update-workflow-rolemap.txt") is None:\n return\n site = context.getSite()\n- portal_workflow = getToolByName(site, \'portal_workflow\')\n+ portal_workflow = getToolByName(site, "portal_workflow")\n portal_workflow.updateRoleMappings()\n \n \n def first_weekday_setup(context):\n- """Set the first day of the week based on the portal\'s locale.\n- """\n+ """Set the first day of the week based on the portal\'s locale."""\n reg = getUtility(IRegistry)\n- if reg.get(\'plone.first_weekday\') is not None:\n+ if reg.get("plone.first_weekday") is not None:\n # don\'t overwrite if it\'s already set\n return\n \n@@ -199,30 +195,29 @@ def first_weekday_setup(context):\n site = getSite()\n # find the locale implied by the portal\'s language\n language = site.Language()\n- parts = (language.split(\'-\') + [None, None])[:3]\n+ parts = (language.split("-") + [None, None])[:3]\n locale = locales.getLocale(*parts)\n # look up first day of week\n- gregorian_calendar = locale.dates.calendars.get(\'gregorian\', None)\n+ gregorian_calendar = locale.dates.calendars.get("gregorian", None)\n if gregorian_calendar is not None:\n- day = gregorian_calendar.week.get(\'firstDay\', 7)\n+ day = gregorian_calendar.week.get("firstDay", 7)\n first = 6 if day == 0 else day - 1\n except LoadLocaleError:\n # If we cannot get the locale, just Sunday as first weekday\n pass\n \n # save setting\n- reg[\'plone.first_weekday\'] = first\n+ reg["plone.first_weekday"] = first\n \n \n def timezone_setup(context):\n- """Set the timezone from server locale\n- """\n- timezone = \'UTC\'\n+ """Set the timezone from server locale"""\n+ timezone = "UTC"\n # TODO: get a /sane/ locale from the server to use.\n # this is not high priority\n # see plone.event.utils\n reg = getUtility(IRegistry)\n if not reg["plone.portal_timezone"]:\n- reg[\'plone.portal_timezone\'] = timezone\n- if not reg[\'plone.available_timezones\']:\n- reg[\'plone.available_timezones\'] = [timezone]\n+ reg["plone.portal_timezone"] = timezone\n+ if not reg["plone.available_timezones"]:\n+ reg["plone.available_timezones"] = [timezone]\ndiff --git a/Products/CMFPlone/skins/plone_scripts/externalEditorEnabled.py b/Products/CMFPlone/skins/plone_scripts/externalEditorEnabled.py\nindex a2c953f854..130499f7de 100644\n--- a/Products/CMFPlone/skins/plone_scripts/externalEditorEnabled.py\n+++ b/Products/CMFPlone/skins/plone_scripts/externalEditorEnabled.py\n@@ -11,15 +11,15 @@\n from Products.CMFPlone.utils import webdav_enabled\n \n \n-portal = getToolByName(context, \'portal_url\').getPortalObject()\n-mtool = getToolByName(portal, \'portal_membership\')\n+portal = getToolByName(context, "portal_url").getPortalObject()\n+mtool = getToolByName(portal, "portal_membership")\n \n if mtool.isAnonymousUser():\n return False\n \n # Check if the member property\n member = mtool.getAuthenticatedMember()\n-if not member.getProperty(\'ext_editor\', False):\n+if not member.getProperty("ext_editor", False):\n return False\n \n if not webdav_enabled(context, container):\ndiff --git a/Products/CMFPlone/skins/plone_scripts/external_edit.py b/Products/CMFPlone/skins/plone_scripts/external_edit.py\nindex 6e61312ab3..859ce01b61 100644\n--- a/Products/CMFPlone/skins/plone_scripts/external_edit.py\n+++ b/Products/CMFPlone/skins/plone_scripts/external_edit.py\n@@ -12,11 +12,15 @@\n \n request = context.REQUEST\n \n-if \'Mac OS X\' in request.get(\'HTTP_USER_AGENT\', \'\'):\n- return context.REQUEST[\'RESPONSE\'].redirect(\n- \'{}/externalEdit_/{}.zem?macosx=1\'.format(context.aq_parent.absolute_url(),\n- url_quote(context.getId())))\n+if "Mac OS X" in request.get("HTTP_USER_AGENT", ""):\n+ return context.REQUEST["RESPONSE"].redirect(\n+ "{}/externalEdit_/{}.zem?macosx=1".format(\n+ context.aq_parent.absolute_url(), url_quote(context.getId())\n+ )\n+ )\n else:\n- return context.REQUEST[\'RESPONSE\'].redirect(\n- \'{}/externalEdit_/{}\'.format(context.aq_parent.absolute_url(),\n- url_quote(context.getId())))\n+ return context.REQUEST["RESPONSE"].redirect(\n+ "{}/externalEdit_/{}".format(\n+ context.aq_parent.absolute_url(), url_quote(context.getId())\n+ )\n+ )\ndiff --git a/Products/CMFPlone/skins/plone_scripts/getFolderContents.py b/Products/CMFPlone/skins/plone_scripts/getFolderContents.py\nindex f60a08c8b1..01ce2b879b 100644\n--- a/Products/CMFPlone/skins/plone_scripts/getFolderContents.py\n+++ b/Products/CMFPlone/skins/plone_scripts/getFolderContents.py\n@@ -13,11 +13,11 @@\n from zExceptions import Forbidden\n \n \n-if container.REQUEST.get(\'PUBLISHED\') is script:\n- raise Forbidden(\'Script may not be published.\')\n+if container.REQUEST.get("PUBLISHED") is script:\n+ raise Forbidden("Script may not be published.")\n \n mtool = context.portal_membership\n-cur_path = \'/\'.join(context.getPhysicalPath())\n+cur_path = "/".join(context.getPhysicalPath())\n path = {}\n \n if not contentFilter:\n@@ -25,33 +25,36 @@\n else:\n contentFilter = dict(contentFilter)\n \n-if not contentFilter.get(\'sort_on\', None):\n- contentFilter[\'sort_on\'] = \'getObjPositionInParent\'\n+if not contentFilter.get("sort_on", None):\n+ contentFilter["sort_on"] = "getObjPositionInParent"\n \n-if contentFilter.get(\'path\', None) is None:\n- path[\'query\'] = cur_path\n- path[\'depth\'] = 1\n- contentFilter[\'path\'] = path\n+if contentFilter.get("path", None) is None:\n+ path["query"] = cur_path\n+ path["depth"] = 1\n+ contentFilter["path"] = path\n \n-show_inactive = mtool.checkPermission(\n- \'Access inactive portal content\', context)\n+show_inactive = mtool.checkPermission("Access inactive portal content", context)\n \n # Provide batching hints to the catalog\n-b_start = int(context.REQUEST.get(\'b_start\', 0))\n-contentFilter[\'b_start\'] = b_start\n+b_start = int(context.REQUEST.get("b_start", 0))\n+contentFilter["b_start"] = b_start\n if batch:\n- contentFilter[\'b_size\'] = b_size\n+ contentFilter["b_size"] = b_size\n \n # Evaluate in catalog context because some containers override queryCatalog\n # with their own unrelated method (Topics)\n-contents = context.portal_catalog.queryCatalog(contentFilter, show_all=1,\n- show_inactive=show_inactive, )\n+contents = context.portal_catalog.queryCatalog(\n+ contentFilter,\n+ show_all=1,\n+ show_inactive=show_inactive,\n+)\n \n if full_objects:\n contents = [b.getObject() for b in contents]\n \n if batch:\n from Products.CMFPlone import Batch\n+\n batch = Batch(contents, b_size, b_start, orphan=0)\n return batch\n \ndiff --git a/Products/CMFPlone/skins/plone_scripts/pretty_title_or_id.py b/Products/CMFPlone/skins/plone_scripts/pretty_title_or_id.py\nindex 25f7e76173..661525c996 100644\n--- a/Products/CMFPlone/skins/plone_scripts/pretty_title_or_id.py\n+++ b/Products/CMFPlone/skins/plone_scripts/pretty_title_or_id.py\n@@ -7,7 +7,7 @@\n ##parameters=default=None\n ##title=\n \n-#autogenerated Ids look like $portal_type.YYYY-MM-DD.integer(random number)\n+# autogenerated Ids look like $portal_type.YYYY-MM-DD.integer(random number)\n \n putils = context.plone_utils\n if default is not None:\ndiff --git a/Products/CMFPlone/skins/plone_scripts/queryCatalog.py b/Products/CMFPlone/skins/plone_scripts/queryCatalog.py\nindex dce2c90911..e00fdee9b7 100644\n--- a/Products/CMFPlone/skins/plone_scripts/queryCatalog.py\n+++ b/Products/CMFPlone/skins/plone_scripts/queryCatalog.py\n@@ -23,7 +23,8 @@\n if REQUEST is None:\n REQUEST = context.REQUEST\n \n-multispace = \'\\u3000\'\n+multispace = "\\u3000"\n+\n \n def quotestring(s):\n return \'"%s"\' % s\n@@ -38,17 +39,16 @@ def quotequery(s):\n raise\n except Exception:\n return s\n- tokens = (\'OR\', \'AND\', \'NOT\')\n- s_tokens = (\'OR\', \'AND\')\n+ tokens = ("OR", "AND", "NOT")\n+ s_tokens = ("OR", "AND")\n check = (0, -1)\n for idx in check:\n if terms[idx].upper() in tokens:\n terms[idx] = quotestring(terms[idx])\n for idx in range(1, len(terms)):\n- if (terms[idx].upper() in s_tokens and\n- terms[idx - 1].upper() in tokens):\n+ if terms[idx].upper() in s_tokens and terms[idx - 1].upper() in tokens:\n terms[idx] = quotestring(terms[idx])\n- return \' \'.join(terms)\n+ return " ".join(terms)\n \n \n # We need to quote parentheses when searching text indices (we use\n@@ -61,43 +61,44 @@ def quote_bad_chars(s):\n \n \n def ensureFriendlyTypes(query):\n- ploneUtils = getToolByName(context, \'plone_utils\')\n- portal_type = query.get(\'portal_type\', [])\n+ ploneUtils = getToolByName(context, "plone_utils")\n+ portal_type = query.get("portal_type", [])\n if not same_type(portal_type, []):\n portal_type = [portal_type]\n- Type = query.get(\'Type\', [])\n+ Type = query.get("Type", [])\n if not same_type(Type, []):\n Type = [Type]\n typesList = portal_type + Type\n if not typesList:\n friendlyTypes = ploneUtils.getUserFriendlyTypes(typesList)\n- query[\'portal_type\'] = friendlyTypes\n+ query["portal_type"] = friendlyTypes\n \n \n def rootAtNavigationRoot(query):\n- if \'path\' not in query:\n- query[\'path\'] = getNavigationRoot(context)\n+ if "path" not in query:\n+ query["path"] = getNavigationRoot(context)\n+\n \n # Avoid creating a session implicitly.\n for k in REQUEST.keys():\n- if k in (\'SESSION\',):\n+ if k in ("SESSION",):\n continue\n v = REQUEST.get(k)\n if v and k in indexes:\n if k in quote_logic_indexes:\n v = quote_bad_chars(v)\n if multispace in v:\n- v = v.replace(multispace, \' \')\n+ v = v.replace(multispace, " ")\n if quote_logic:\n v = quotequery(v)\n query[k] = v\n show_query = 1\n- elif k.endswith(\'_usage\'):\n+ elif k.endswith("_usage"):\n key = k[:-6]\n- param, value = v.split(\':\')\n+ param, value = v.split(":")\n second_pass[key] = {param: value}\n- elif k in (\'sort_on\', \'sort_order\', \'sort_limit\'):\n- if k == \'sort_limit\' and not same_type(v, 0):\n+ elif k in ("sort_on", "sort_order", "sort_limit"):\n+ if k == "sort_limit" and not same_type(v, 0):\n query[k] = int(v)\n else:\n query[k] = v\n@@ -107,7 +108,7 @@ def rootAtNavigationRoot(query):\n qs = query.get(k)\n if qs is None:\n continue\n- query[k] = q = {\'query\': qs}\n+ query[k] = q = {"query": qs}\n q.update(v)\n \n # doesn\'t normal call catalog unless some field has been queried\n@@ -119,7 +120,7 @@ def rootAtNavigationRoot(query):\n ensureFriendlyTypes(query)\n if use_navigation_root:\n rootAtNavigationRoot(query)\n- query[\'show_inactive\'] = show_inactive\n+ query["show_inactive"] = show_inactive\n results = catalog(**query)\n except ParseError:\n pass\ndiff --git a/Products/CMFPlone/skins/plone_scripts/toLocalizedTime.py b/Products/CMFPlone/skins/plone_scripts/toLocalizedTime.py\nindex 1e86da1c3b..17203ba68c 100644\n--- a/Products/CMFPlone/skins/plone_scripts/toLocalizedTime.py\n+++ b/Products/CMFPlone/skins/plone_scripts/toLocalizedTime.py\n@@ -10,5 +10,6 @@\n # The time parameter must be either a string that is suitable for\n # initializing a DateTime or a DateTime object.\n # Returns a localized string.\n-return context.restrictedTraverse(\'@@plone\').toLocalizedTime(\n- time, long_format, time_only)\n+return context.restrictedTraverse("@@plone").toLocalizedTime(\n+ time, long_format, time_only\n+)\ndiff --git a/Products/CMFPlone/skins/plone_scripts/translate.py b/Products/CMFPlone/skins/plone_scripts/translate.py\nindex e1d19bc95b..ecc3e3fa0d 100644\n--- a/Products/CMFPlone/skins/plone_scripts/translate.py\n+++ b/Products/CMFPlone/skins/plone_scripts/translate.py\n@@ -9,8 +9,8 @@\n from zExceptions import Forbidden\n \n \n-if container.REQUEST.get(\'PUBLISHED\') is script:\n- raise Forbidden(\'Script may not be published.\')\n+if container.REQUEST.get("PUBLISHED") is script:\n+ raise Forbidden("Script may not be published.")\n \n # handle the possible "nothing" condition in folder_contents.pt ln 21\n # gracefully\n@@ -21,21 +21,23 @@\n \n \n # get tool\n-tool = getToolByName(context, \'translation_service\')\n+tool = getToolByName(context, "translation_service")\n \n # this returns type unicode\n-value = tool.translate(msgid,\n- domain,\n- mapping,\n- context=context,\n- target_language=target_language,\n- default=default)\n+value = tool.translate(\n+ msgid,\n+ domain,\n+ mapping,\n+ context=context,\n+ target_language=target_language,\n+ default=default,\n+)\n \n if not value and default is None:\n value = msgid\n \n for k, v in mapping.items():\n- value = value.replace(\'${%s}\' % k, v)\n+ value = value.replace("${%s}" % k, v)\n \n if escape_for_js:\n value = value.replace("\'", "\\\\\'")\ndiff --git a/Products/CMFPlone/skins/plone_scripts/utranslate.py b/Products/CMFPlone/skins/plone_scripts/utranslate.py\nindex e7cb75e147..8dedd8805a 100644\n--- a/Products/CMFPlone/skins/plone_scripts/utranslate.py\n+++ b/Products/CMFPlone/skins/plone_scripts/utranslate.py\n@@ -9,8 +9,8 @@\n from zExceptions import Forbidden\n \n \n-if container.REQUEST.get(\'PUBLISHED\') is script:\n- raise Forbidden(\'Script may not be published.\')\n+if container.REQUEST.get("PUBLISHED") is script:\n+ raise Forbidden("Script may not be published.")\n \n # handle the possible "nothing" condition in folder_contents.pt ln 21\n # gracefully\n@@ -21,21 +21,23 @@\n \n \n # get tool\n-tool = getToolByName(context, \'translation_service\')\n+tool = getToolByName(context, "translation_service")\n \n # this returns type unicode\n-value = tool.utranslate(msgid,\n- domain,\n- mapping,\n- context=context,\n- target_language=target_language,\n- default=default)\n+value = tool.utranslate(\n+ msgid,\n+ domain,\n+ mapping,\n+ context=context,\n+ target_language=target_language,\n+ default=default,\n+)\n \n if not value and default is None:\n value = msgid\n \n for k, v in mapping.items():\n- value = value.replace(\'${%s}\' % k, v)\n+ value = value.replace("${%s}" % k, v)\n \n if escape_for_js:\n value = value.replace("\'", "\\\\\'")\ndiff --git a/Products/CMFPlone/testing.py b/Products/CMFPlone/testing.py\nindex b65165f6fe..4b178f00b0 100644\n--- a/Products/CMFPlone/testing.py\n+++ b/Products/CMFPlone/testing.py\n@@ -22,95 +22,71 @@\n \n \n class ProductsCMFPloneLayer(PloneSandboxLayer):\n-\n defaultBases = (PLONE_APP_CONTENTTYPES_FIXTURE,)\n \n def setUpZope(self, app, configurationContext):\n import Products.CMFPlone\n+\n xmlconfig.file(\n- \'configure.zcml\',\n- Products.CMFPlone,\n- context=configurationContext\n+ "configure.zcml", Products.CMFPlone, context=configurationContext\n )\n xmlconfig.file(\n- \'configure.zcml\',\n- Products.CMFPlone.tests,\n- context=configurationContext\n+ "configure.zcml", Products.CMFPlone.tests, context=configurationContext\n )\n \n def setUpPloneSite(self, portal):\n- portal.acl_users.userFolderAddUser(\n- \'admin\',\n- TEST_USER_PASSWORD,\n- [\'Manager\'],\n- []\n- )\n- login(portal, \'admin\')\n+ portal.acl_users.userFolderAddUser("admin", TEST_USER_PASSWORD, ["Manager"], [])\n+ login(portal, "admin")\n portal.portal_workflow.setDefaultChain("simple_publication_workflow")\n- setRoles(portal, TEST_USER_ID, [\'Manager\'])\n- portal.invokeFactory(\n- "Folder",\n- id="test-folder",\n- title="Test Folder"\n- )\n+ setRoles(portal, TEST_USER_ID, ["Manager"])\n+ portal.invokeFactory("Folder", id="test-folder", title="Test Folder")\n # XXX: this is needed for tests that rely on the Members folder to be\n # present. This folder is otherwise created by a setup handler in\n # ATContentTypes, but that package is optional now.\n- if \'Members\' not in portal.keys():\n- portal.invokeFactory(\n- "Folder",\n- id="Members",\n- title="Members"\n- )\n+ if "Members" not in portal.keys():\n+ portal.invokeFactory("Folder", id="Members", title="Members")\n \n portal._original_MailHost = portal.MailHost\n- mail_host = MockMailHost(\'MailHost\')\n- mail_host.smtp_host = \'localhost\'\n+ mail_host = MockMailHost("MailHost")\n+ mail_host.smtp_host = "localhost"\n portal.MailHost = mail_host\n site_manager = getSiteManager(portal)\n site_manager.unregisterUtility(provided=IMailHost)\n site_manager.registerUtility(mail_host, IMailHost)\n \n def tearDownPloneSite(self, portal):\n- login(portal, \'admin\')\n- setRoles(portal, TEST_USER_ID, [\'Manager\'])\n- portal.manage_delObjects([\'test-folder\'])\n+ login(portal, "admin")\n+ setRoles(portal, TEST_USER_ID, ["Manager"])\n+ portal.manage_delObjects(["test-folder"])\n \n portal.MailHost = portal._original_MailHost\n sm = getSiteManager(context=portal)\n sm.unregisterUtility(provided=IMailHost)\n- sm.registerUtility(\n- aq_base(portal._original_MailHost),\n- provided=IMailHost\n- )\n+ sm.registerUtility(aq_base(portal._original_MailHost), provided=IMailHost)\n \n \n PRODUCTS_CMFPLONE_FIXTURE = ProductsCMFPloneLayer()\n \n PRODUCTS_CMFPLONE_INTEGRATION_TESTING = IntegrationTesting(\n- bases=(PRODUCTS_CMFPLONE_FIXTURE,),\n- name="CMFPloneLayer:Integration"\n+ bases=(PRODUCTS_CMFPLONE_FIXTURE,), name="CMFPloneLayer:Integration"\n )\n PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING = FunctionalTesting(\n- bases=(PRODUCTS_CMFPLONE_FIXTURE,),\n- name="CMFPloneLayer:Functional"\n+ bases=(PRODUCTS_CMFPLONE_FIXTURE,), name="CMFPloneLayer:Functional"\n )\n \n PRODUCTS_CMFPLONE_ROBOT_REMOTE_LIBRARY_FIXTURE = RemoteLibraryLayer(\n- bases=(\n- PLONE_FIXTURE,\n- ),\n+ bases=(PLONE_FIXTURE,),\n libraries=(AutoLogin, Content, CMFPloneRemoteKeywords),\n- name="CMFPloneRobotRemoteLibrary:RobotRemote"\n+ name="CMFPloneRobotRemoteLibrary:RobotRemote",\n )\n \n PRODUCTS_CMFPLONE_ROBOT_TESTING = FunctionalTesting(\n bases=(\n PRODUCTS_CMFPLONE_FIXTURE,\n PRODUCTS_CMFPLONE_ROBOT_REMOTE_LIBRARY_FIXTURE,\n- zope.WSGI_SERVER_FIXTURE\n+ zope.WSGI_SERVER_FIXTURE,\n ),\n- name="CMFPloneLayer:Acceptance"\n+ name="CMFPloneLayer:Acceptance",\n )\n \n-optionflags = (doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE)\n+optionflags = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE\ndiff --git a/Products/CMFPlone/tests/PloneTestCase.py b/Products/CMFPlone/tests/PloneTestCase.py\nindex adaab0fc59..219f54c79a 100644\n--- a/Products/CMFPlone/tests/PloneTestCase.py\n+++ b/Products/CMFPlone/tests/PloneTestCase.py\n@@ -16,15 +16,15 @@\n \n class PloneTestCase(PloneTestCase):\n """This is a stub now, but in case you want to try\n- something fancy on Your Branch (tm), put it here.\n+ something fancy on Your Branch (tm), put it here.\n """\n \n def setRequestMethod(self, method):\n- self.app.REQUEST.set(\'REQUEST_METHOD\', method)\n+ self.app.REQUEST.set("REQUEST_METHOD", method)\n self.app.REQUEST.method = method\n \n def getAuthenticator(self):\n- tag = AuthenticatorView(\'context\', \'request\').authenticator()\n+ tag = AuthenticatorView("context", "request").authenticator()\n pattern = r\' \', re.S)\n-RE_REMOVE_AUTH = re.compile(r\'\\_authenticator\\=.*?\\"\', re.S)\n+RE_REMOVE_AUTH = re.compile(r"\\_authenticator\\=.*?\\"", re.S)\n \n \n class TestPloneToolBrowserDefault(unittest.TestCase):\n- """Test the PloneTool\'s browserDefault() method in various use cases.\n- """\n+ """Test the PloneTool\'s browserDefault() method in various use cases."""\n \n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n \n # disable diazo theming\n self.portal.portal_registry[\n- \'plone.app.theming.interfaces.IThemeSettings.enabled\'\n+ "plone.app.theming.interfaces.IThemeSettings.enabled"\n ] = False\n \n # disable auto-CSRF\n from plone.protect import auto\n+\n auto.CSRF_DISABLED = True\n \n- unrestricted_construct_instance(\'Folder\', self.portal, \'folder\')\n- unrestricted_construct_instance(\'Document\', self.portal, \'document\')\n- unrestricted_construct_instance(\'File\', self.portal, \'file\')\n- self.portal.file.file = NamedBlobFile(\'foo\', \'text/plain\', \'foo.txt\')\n+ unrestricted_construct_instance("Folder", self.portal, "folder")\n+ unrestricted_construct_instance("Document", self.portal, "document")\n+ unrestricted_construct_instance("File", self.portal, "file")\n+ self.portal.file.file = NamedBlobFile("foo", "text/plain", "foo.txt")\n transaction.commit()\n \n self.putils = getToolByName(self.portal, "plone_utils")\n- self.browser = Browser(self.layer[\'app\'])\n+ self.browser = Browser(self.layer["app"])\n self.browser.addHeader(\n- \'Authorization\', \'Basic {}:{}\'.format(\n+ "Authorization",\n+ "Basic {}:{}".format(\n TEST_USER_NAME,\n TEST_USER_PASSWORD,\n- )\n+ ),\n )\n \n def tearDown(self):\n from plone.protect import auto\n+\n auto.CSRF_DISABLED = False\n \n def compareLayoutVsView(self, obj, path="", viewaction=None):\n if viewaction is None:\n- if hasattr(aq_base(obj), \'getLayout\'):\n+ if hasattr(aq_base(obj), "getLayout"):\n viewaction = obj.getLayout()\n else:\n- viewaction = obj.getTypeInfo().getActionInfo(\n- \'object/view\'\n- )[\'url\'].split(\'/\')[-1]\n+ viewaction = (\n+ obj.getTypeInfo().getActionInfo("object/view")["url"].split("/")[-1]\n+ )\n \n- self.layer[\'app\'].REQUEST[\'ACTUAL_URL\'] = obj.absolute_url()\n+ self.layer["app"].REQUEST["ACTUAL_URL"] = obj.absolute_url()\n resolved = obj.restrictedTraverse(viewaction)()\n \n # rendering the view cooked the resource registry,\n@@ -84,68 +86,79 @@ def compareLayoutVsView(self, obj, path="", viewaction=None):\n resolved = safe_text(resolved)\n \n # request/ACTUAL_URL is fubar in tests, remove lines that depend on it\n- resolved = RE_REMOVE_DOCCONT.sub(\'\', resolved)\n- resolved = RE_REMOVE_SKIPNAV.sub(\'\', resolved)\n- resolved = RE_REMOVE_TABS.sub(\'\', resolved)\n+ resolved = RE_REMOVE_DOCCONT.sub("", resolved)\n+ resolved = RE_REMOVE_SKIPNAV.sub("", resolved)\n+ resolved = RE_REMOVE_TABS.sub("", resolved)\n resolved = RE_REMOVE_AUTH.sub(\'"\', resolved)\n \n- body = RE_REMOVE_DOCCONT.sub(\'\', body)\n- body = RE_REMOVE_SKIPNAV.sub(\'\', body)\n- body = RE_REMOVE_TABS.sub(\'\', body)\n+ body = RE_REMOVE_DOCCONT.sub("", body)\n+ body = RE_REMOVE_SKIPNAV.sub("", body)\n+ body = RE_REMOVE_TABS.sub("", body)\n body = RE_REMOVE_AUTH.sub(\'"\', body)\n \n if not body:\n- self.fail(\'No body in response\')\n+ self.fail("No body in response")\n \n if not body == resolved:\n- diff = difflib.unified_diff(body.split("\\n"),\n- resolved.split("\\n"))\n+ diff = difflib.unified_diff(body.split("\\n"), resolved.split("\\n"))\n self.fail("\\n".join([line for line in diff]))\n \n def compareLayoutVsCall(self, obj):\n- if hasattr(aq_base(obj), \'getLayout\'):\n+ if hasattr(aq_base(obj), "getLayout"):\n viewaction = obj.getLayout()\n else:\n- viewaction = obj.getTypeInfo().getActionInfo(\n- \'object/view\')[\'url\'].split(\'/\')[-1]\n+ viewaction = (\n+ obj.getTypeInfo().getActionInfo("object/view")["url"].split("/")[-1]\n+ )\n \n viewed = obj.restrictedTraverse(viewaction)()\n called = obj()\n \n # request/ACTUAL_URL is fubar in tests, remove line that depends on it\n- called = RE_REMOVE_DOCCONT.sub(\'\', called)\n- viewed = RE_REMOVE_DOCCONT.sub(\'\', viewed)\n+ called = RE_REMOVE_DOCCONT.sub("", called)\n+ viewed = RE_REMOVE_DOCCONT.sub("", viewed)\n \n if not called or not viewed:\n- self.fail(\'No body in response\')\n+ self.fail("No body in response")\n \n if not viewed == called:\n- diff = difflib.unified_diff(viewed.split("\\n"),\n- called.split("\\n"))\n+ diff = difflib.unified_diff(viewed.split("\\n"), called.split("\\n"))\n self.fail("\\n".join([line for line in diff]))\n \n # Folders with IBrowserDefault - default page, index_html, global default\n \n def testBrowserDefaultMixinFolderDefaultPage(self):\n- self.portal.folder.invokeFactory(\'Document\', \'default\')\n- self.portal.folder.setDefaultPage(\'default\')\n- self.assertEqual(self.putils.browserDefault(self.portal.folder),\n- (self.portal.folder, [\'default\'],))\n+ self.portal.folder.invokeFactory("Document", "default")\n+ self.portal.folder.setDefaultPage("default")\n+ self.assertEqual(\n+ self.putils.browserDefault(self.portal.folder),\n+ (\n+ self.portal.folder,\n+ ["default"],\n+ ),\n+ )\n \n def testBrowserDefaultMixinFolderIndexHtml(self):\n- self.portal.folder.invokeFactory(\'Document\', \'default\')\n- self.portal.folder.setDefaultPage(\'default\')\n+ self.portal.folder.invokeFactory("Document", "default")\n+ self.portal.folder.setDefaultPage("default")\n # index_html should always win - it\'s an explicit override!\n- self.portal.folder.invokeFactory(\'Document\', \'index_html\')\n- self.assertEqual(self.putils.browserDefault(self.portal.folder),\n- (self.portal.folder, [\'index_html\'],))\n+ self.portal.folder.invokeFactory("Document", "index_html")\n+ self.assertEqual(\n+ self.putils.browserDefault(self.portal.folder),\n+ (\n+ self.portal.folder,\n+ ["index_html"],\n+ ),\n+ )\n \n def testBrowserDefaultMixinFolderGlobalDefaultPage(self):\n registry = getUtility(IRegistry)\n- registry[\'plone.default_page\'] = [\'foo\']\n- self.portal.folder.invokeFactory(\'Document\', \'foo\')\n- self.assertEqual(self.putils.browserDefault(self.portal.folder),\n- (self.portal.folder, [\'foo\']))\n+ registry["plone.default_page"] = ["foo"]\n+ self.portal.folder.invokeFactory("Document", "foo")\n+ self.assertEqual(\n+ self.putils.browserDefault(self.portal.folder),\n+ (self.portal.folder, ["foo"]),\n+ )\n \n # View action resolution (last fallback)\n \n@@ -164,17 +177,17 @@ def testBrowserDefaultMixinFileViewMethodGetsTemplate(self):\n def testBrowserDefaultMixinFileDumpsContent(self):\n self.browser.open(self.portal.file.absolute_url())\n data = self.portal.file.file.data\n- self.assertEqual(self.browser.contents.encode(\'utf8\'), data)\n+ self.assertEqual(self.browser.contents.encode("utf8"), data)\n \n # Ensure index_html acquisition\n \n def testIndexHtmlNotAcquired(self):\n- self.portal.folder.invokeFactory(\'Document\', \'index_html\')\n- self.portal.folder.invokeFactory(\'Folder\', \'subfolder\')\n+ self.portal.folder.invokeFactory("Document", "index_html")\n+ self.portal.folder.invokeFactory("Folder", "subfolder")\n layout = self.portal.folder.getLayout()\n self.assertEqual(\n self.putils.browserDefault(self.portal.folder.subfolder),\n- (self.portal.folder.subfolder, [layout])\n+ (self.portal.folder.subfolder, [layout]),\n )\n \n # Test behaviour of __call__\n@@ -186,8 +199,8 @@ def testCallFolderWithoutDefaultPageGivesTemplate(self):\n self.compareLayoutVsCall(self.portal.folder)\n \n def testCallFolderWithDefaultPageGivesTemplate(self):\n- self.portal.folder.invokeFactory(\'Document\', \'doc\')\n- self.portal.folder.setDefaultPage(\'doc\')\n+ self.portal.folder.invokeFactory("Document", "doc")\n+ self.portal.folder.setDefaultPage("doc")\n self.compareLayoutVsCall(self.portal.folder)\n \n def testCallFileGivesTemplate(self):\n@@ -197,8 +210,8 @@ def testCallFileGivesTemplate(self):\n \n def testReselectingDefaultLayoutAfterDefaultPageWorks(self):\n defaultLayout = self.portal.folder.getDefaultLayout()\n- self.portal.folder.invokeFactory(\'Document\', \'default\')\n- self.portal.folder.setDefaultPage(\'default\')\n+ self.portal.folder.invokeFactory("Document", "default")\n+ self.portal.folder.setDefaultPage("default")\n self.portal.folder.setLayout(defaultLayout)\n self.assertEqual(self.portal.folder.getDefaultPage(), None)\n self.assertEqual(self.portal.folder.defaultView(), defaultLayout)\n@@ -206,11 +219,11 @@ def testReselectingDefaultLayoutAfterDefaultPageWorks(self):\n def testBrowserDefaultMixinWithoutFtiGivesSensibleError(self):\n # Test for issue http://dev.plone.org/plone/ticket/5676\n # Ensure that the error displayed for missing FTIs is not so cryptic\n- getToolByName(self.portal, "portal_types")._delOb(\'Document\')\n+ getToolByName(self.portal, "portal_types")._delOb("Document")\n \n- self.assertRaises(AttributeError,\n- self.portal.plone_utils.browserDefault,\n- self.portal.document)\n+ self.assertRaises(\n+ AttributeError, self.portal.plone_utils.browserDefault, self.portal.document\n+ )\n \n def testFolderDefaultPageSameAsSelfWithPageMissing(self):\n # We need to avoid infinite recursion in the case that\n@@ -218,43 +231,54 @@ def testFolderDefaultPageSameAsSelfWithPageMissing(self):\n # page and then deleted. See http://dev.plone.org/plone/ticket/5704\n # We should fallback on the default layout folder_listing\n f = self.portal.folder\n- f.invokeFactory(\'Document\', f.getId())\n+ f.invokeFactory("Document", f.getId())\n f.setDefaultPage(f.getId())\n- self.assertEqual(self.putils.browserDefault(f),\n- (f, [f.getId()],))\n+ self.assertEqual(\n+ self.putils.browserDefault(f),\n+ (\n+ f,\n+ [f.getId()],\n+ ),\n+ )\n f._delObject(f.getId())\n self.assertTrue(\n- self.putils.browserDefault(f) == (f, [\'folder_listing\'],)\n- or\n- self.putils.browserDefault(f) == (f, [\'listing_view\'],)\n+ self.putils.browserDefault(f)\n+ == (\n+ f,\n+ ["folder_listing"],\n+ )\n+ or self.putils.browserDefault(f)\n+ == (\n+ f,\n+ ["listing_view"],\n+ )\n # plone.app.contenttypes has unified views\n )\n \n def testDefaultPageSetting(self):\n registry = getUtility(IRegistry)\n- default = registry.get(\'plone.default_page\', [])\n+ default = registry.get("plone.default_page", [])\n self.assertEqual(\n- default,\n- [\'index_html\', \'index.html\', \'index.htm\', \'FrontPage\']\n+ default, ["index_html", "index.html", "index.htm", "FrontPage"]\n )\n \n \n class TestPortalBrowserDefault(unittest.TestCase):\n- """Test the BrowserDefaultMixin as implemented by the root portal object\n- """\n+ """Test the BrowserDefaultMixin as implemented by the root portal object"""\n \n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n \n # Make sure we have the front page; the portal generator should take\n # care of this, but let\'s not be dependent on that in the test\n- if not \'front-page\' in self.portal.objectIds():\n- self.portal.invokeFactory(\'Document\', \'front-page\',\n- title=\'Welcome to Plone\')\n- self.portal.setDefaultPage(\'front-page\')\n+ if not "front-page" in self.portal.objectIds():\n+ self.portal.invokeFactory(\n+ "Document", "front-page", title="Welcome to Plone"\n+ )\n+ self.portal.setDefaultPage("front-page")\n \n def assertFalseDiff(self, text1, text2):\n """\n@@ -266,20 +290,27 @@ def assertFalseDiff(self, text1, text2):\n self.fail("\\n".join([line for line in diff]))\n \n def testCall(self):\n- self.portal.setLayout(\'folder_listing\')\n+ self.portal.setLayout("folder_listing")\n resolved = self.portal()\n- target = self.portal.unrestrictedTraverse(\'folder_listing\')()\n+ target = self.portal.unrestrictedTraverse("folder_listing")()\n self.assertFalseDiff(resolved, target)\n \n def testDefaultViews(self):\n- self.assertEqual(self.portal.getLayout(), \'document_view\')\n- self.assertEqual(self.portal.getDefaultPage(), \'front-page\')\n- self.assertEqual(self.portal.defaultView(), \'front-page\')\n- self.assertEqual(self.portal.getDefaultLayout(), \'document_view\')\n+ self.assertEqual(self.portal.getLayout(), "document_view")\n+ self.assertEqual(self.portal.getDefaultPage(), "front-page")\n+ self.assertEqual(self.portal.defaultView(), "front-page")\n+ self.assertEqual(self.portal.getDefaultLayout(), "document_view")\n layoutKeys = [v[0] for v in self.portal.getAvailableLayouts()]\n- self.assertTrue(\'listing_view\' in layoutKeys)\n- self.assertEqual(self.portal.__browser_default__(None),\n- (self.portal, [\'front-page\', ]))\n+ self.assertTrue("listing_view" in layoutKeys)\n+ self.assertEqual(\n+ self.portal.__browser_default__(None),\n+ (\n+ self.portal,\n+ [\n+ "front-page",\n+ ],\n+ ),\n+ )\n \n def testCanSetLayout(self):\n self.assertTrue(self.portal.canSetLayout())\n@@ -287,18 +318,17 @@ def testCanSetLayout(self):\n self.assertFalse(self.portal.canSetLayout()) # Not permitted\n \n def testSetLayout(self):\n- self.portal.setLayout(\'summary_view\')\n- self.assertEqual(self.portal.getLayout(), \'summary_view\')\n+ self.portal.setLayout("summary_view")\n+ self.assertEqual(self.portal.getLayout(), "summary_view")\n self.assertEqual(self.portal.getDefaultPage(), None)\n- self.assertEqual(self.portal.defaultView(), \'summary_view\')\n- self.assertEqual(self.portal.getDefaultLayout(), \'document_view\')\n+ self.assertEqual(self.portal.defaultView(), "summary_view")\n+ self.assertEqual(self.portal.getDefaultLayout(), "document_view")\n layoutKeys = [v[0] for v in self.portal.getAvailableLayouts()]\n- self.assertTrue(\'summary_view\' in layoutKeys)\n+ self.assertTrue("summary_view" in layoutKeys)\n \n view = self.portal.view()\n browserDefault = self.portal.__browser_default__(None)[1][0]\n- browserDefaultResolved = \\\n- self.portal.unrestrictedTraverse(browserDefault)()\n+ browserDefaultResolved = self.portal.unrestrictedTraverse(browserDefault)()\n template = self.portal.defaultView()\n templateResolved = self.portal.unrestrictedTraverse(template)()\n \n@@ -307,58 +337,59 @@ def testSetLayout(self):\n \n def testCanSetDefaultPage(self):\n self.assertTrue(self.portal.canSetDefaultPage())\n- self.portal.invokeFactory(\'Document\', \'ad\')\n+ self.portal.invokeFactory("Document", "ad")\n self.assertFalse(self.portal.ad.canSetDefaultPage()) # Not folderish\n self.portal.manage_permission("Modify view template", [], 0)\n self.assertFalse(self.portal.canSetDefaultPage()) # Not permitted\n \n def testSetDefaultPage(self):\n- self.portal.invokeFactory(\'Document\', \'ad\')\n- self.portal.setDefaultPage(\'ad\')\n- self.assertEqual(self.portal.getDefaultPage(), \'ad\')\n- self.assertEqual(self.portal.defaultView(), \'ad\')\n- self.assertEqual(self.portal.__browser_default__(None),\n- (self.portal, [\'ad\', ]))\n+ self.portal.invokeFactory("Document", "ad")\n+ self.portal.setDefaultPage("ad")\n+ self.assertEqual(self.portal.getDefaultPage(), "ad")\n+ self.assertEqual(self.portal.defaultView(), "ad")\n+ self.assertEqual(\n+ self.portal.__browser_default__(None),\n+ (\n+ self.portal,\n+ [\n+ "ad",\n+ ],\n+ ),\n+ )\n \n # still have layout settings\n- self.assertEqual(self.portal.getLayout(), \'document_view\')\n- self.assertEqual(self.portal.getDefaultLayout(), \'document_view\')\n+ self.assertEqual(self.portal.getLayout(), "document_view")\n+ self.assertEqual(self.portal.getDefaultLayout(), "document_view")\n layoutKeys = [v[0] for v in self.portal.getAvailableLayouts()]\n- self.assertTrue(\'listing_view\' in layoutKeys)\n+ self.assertTrue("listing_view" in layoutKeys)\n \n def testSetDefaultPageUpdatesCatalog(self):\n # Ensure that Default page changes update the catalog\n cat = getToolByName(self.portal, "portal_catalog")\n- self.portal.invokeFactory(\'Document\', \'ad\')\n- self.portal.invokeFactory(\'Document\', \'other\')\n- self.assertEqual(\n- len(cat(getId=[\'ad\', \'other\'], is_default_page=True)), 0)\n- self.portal.setDefaultPage(\'ad\')\n- self.assertEqual(\n- len(cat(getId=\'ad\', is_default_page=True)), 1)\n- self.portal.setDefaultPage(\'other\')\n- self.assertEqual(\n- len(cat(getId=\'other\', is_default_page=True)), 1)\n- self.assertEqual(\n- len(cat(getId=\'ad\', is_default_page=True)), 0)\n+ self.portal.invokeFactory("Document", "ad")\n+ self.portal.invokeFactory("Document", "other")\n+ self.assertEqual(len(cat(getId=["ad", "other"], is_default_page=True)), 0)\n+ self.portal.setDefaultPage("ad")\n+ self.assertEqual(len(cat(getId="ad", is_default_page=True)), 1)\n+ self.portal.setDefaultPage("other")\n+ self.assertEqual(len(cat(getId="other", is_default_page=True)), 1)\n+ self.assertEqual(len(cat(getId="ad", is_default_page=True)), 0)\n self.portal.setDefaultPage(None)\n- self.assertEqual(\n- len(cat(getId=[\'ad\', \'other\'], is_default_page=True)), 0)\n+ self.assertEqual(len(cat(getId=["ad", "other"], is_default_page=True)), 0)\n \n def testSetLayoutUnsetsDefaultPage(self):\n- self.portal.invokeFactory(\'Document\', \'ad\')\n- self.portal.setDefaultPage(\'ad\')\n- self.assertEqual(self.portal.getDefaultPage(), \'ad\')\n- self.assertEqual(self.portal.defaultView(), \'ad\')\n- self.portal.setLayout(\'folder_listing\')\n+ self.portal.invokeFactory("Document", "ad")\n+ self.portal.setDefaultPage("ad")\n+ self.assertEqual(self.portal.getDefaultPage(), "ad")\n+ self.assertEqual(self.portal.defaultView(), "ad")\n+ self.portal.setLayout("folder_listing")\n \n self.assertFalseDiff(self.portal.getDefaultPage(), None)\n- self.assertFalseDiff(self.portal.defaultView(), \'folder_listing\')\n+ self.assertFalseDiff(self.portal.defaultView(), "folder_listing")\n \n view = self.portal.view()\n browserDefault = self.portal.__browser_default__(None)[1][0]\n- browserDefaultResolved = \\\n- self.portal.unrestrictedTraverse(browserDefault)()\n+ browserDefaultResolved = self.portal.unrestrictedTraverse(browserDefault)()\n template = self.portal.defaultView()\n templateResolved = self.portal.unrestrictedTraverse(template)()\n \n@@ -366,14 +397,22 @@ def testSetLayoutUnsetsDefaultPage(self):\n self.assertFalseDiff(view, templateResolved)\n \n def testMissingTemplatesIgnored(self):\n- self.portal.getTypeInfo() \\\n- .manage_changeProperties(view_methods=[\'document_view\', \'foo\'])\n+ self.portal.getTypeInfo().manage_changeProperties(\n+ view_methods=["document_view", "foo"]\n+ )\n views = [v[0] for v in self.portal.getAvailableLayouts()]\n- self.assertTrue(views == [\'document_view\'])\n+ self.assertTrue(views == ["document_view"])\n \n def testMissingPageIgnored(self):\n- self.portal.setDefaultPage(\'inexistent\')\n+ self.portal.setDefaultPage("inexistent")\n self.assertEqual(self.portal.getDefaultPage(), None)\n- self.assertEqual(self.portal.defaultView(), \'document_view\')\n- self.assertEqual(self.portal.__browser_default__(None),\n- (self.portal, [\'document_view\', ]))\n+ self.assertEqual(self.portal.defaultView(), "document_view")\n+ self.assertEqual(\n+ self.portal.__browser_default__(None),\n+ (\n+ self.portal,\n+ [\n+ "document_view",\n+ ],\n+ ),\n+ )\ndiff --git a/Products/CMFPlone/tests/testBrowserLayerPrecedence.py b/Products/CMFPlone/tests/testBrowserLayerPrecedence.py\nindex e11c0bd5af..ec8882bc5d 100644\n--- a/Products/CMFPlone/tests/testBrowserLayerPrecedence.py\n+++ b/Products/CMFPlone/tests/testBrowserLayerPrecedence.py\n@@ -16,9 +16,8 @@ class IAdditiveLayer(Interface):\n \n \n class TestBrowserLayerPrecedence(PloneTestCase):\n-\n def _get_request_interfaces(self):\n- request = self.layer[\'request\']\n+ request = self.layer["request"]\n # Reset _plonebrowerlayer_ marker, so that we can still register\n # additional layers for testing. (WTF here?)\n del request._plonebrowserlayer_\n@@ -27,9 +26,8 @@ def _get_request_interfaces(self):\n return iro\n \n def testCustomBrowserLayerHasPrecedenceOverDefaultLayer(self):\n- register_layer(IAdditiveLayer, \'Plone.testlayer\')\n+ register_layer(IAdditiveLayer, "Plone.testlayer")\n iro = self._get_request_interfaces()\n- unregister_layer(\'Plone.testlayer\')\n+ unregister_layer("Plone.testlayer")\n \n- self.assertTrue(iro.index(IAdditiveLayer) <\n- iro.index(IDefaultBrowserLayer))\n+ self.assertTrue(iro.index(IAdditiveLayer) < iro.index(IDefaultBrowserLayer))\ndiff --git a/Products/CMFPlone/tests/testCSRFProtection.py b/Products/CMFPlone/tests/testCSRFProtection.py\nindex 704300b4e7..abd2467b43 100644\n--- a/Products/CMFPlone/tests/testCSRFProtection.py\n+++ b/Products/CMFPlone/tests/testCSRFProtection.py\n@@ -9,80 +9,82 @@\n \n \n class AuthenticatorTestCase(PloneTestCase):\n-\n def afterSetUp(self):\n- self.setRoles((\'Manager\',))\n+ self.setRoles(("Manager",))\n \n def test_KeyManager(self):\n- self.assertTrue(queryUtility(IKeyManager), \'key manager not found\')\n+ self.assertTrue(queryUtility(IKeyManager), "key manager not found")\n \n- def checkAuthenticator(self, path, query=\'\', status=200):\n- credentials = f\'{TEST_USER_NAME}:{TEST_USER_PASSWORD}\'\n- path = \'/\' + self.portal.absolute_url(relative=True) + path\n- data = BytesIO(query.encode(\'utf8\'))\n+ def checkAuthenticator(self, path, query="", status=200):\n+ credentials = f"{TEST_USER_NAME}:{TEST_USER_PASSWORD}"\n+ path = "/" + self.portal.absolute_url(relative=True) + path\n+ data = BytesIO(query.encode("utf8"))\n # without authenticator...\n- response = self.publish(path=path, basic=credentials, env={},\n- request_method=\'POST\', stdin=data)\n+ response = self.publish(\n+ path=path, basic=credentials, env={}, request_method="POST", stdin=data\n+ )\n self.assertEqual(response.getStatus(), 403)\n # with authenticator...\n- tag = AuthenticatorView(\'context\', \'request\').authenticator()\n+ tag = AuthenticatorView("context", "request").authenticator()\n token = tag.split(\'"\')[5]\n- query = query + \'&_authenticator=%s\' % token\n- data = BytesIO(query.encode(\'utf8\'))\n- response = self.publish(path=path, basic=credentials, env={},\n- request_method=\'POST\', stdin=data)\n+ query = query + "&_authenticator=%s" % token\n+ data = BytesIO(query.encode("utf8"))\n+ response = self.publish(\n+ path=path, basic=credentials, env={}, request_method="POST", stdin=data\n+ )\n self.assertEqual(response.getStatus(), status)\n \n def test_PloneTool_deleteObjectsByPaths(self):\n- self.assertTrue(self.portal.get(\'news\', None))\n- self.checkAuthenticator(\n- \'/plone_utils/deleteObjectsByPaths\',\n- \'paths:list=news\')\n- self.assertFalse(self.portal.get(\'news\', None))\n+ self.assertTrue(self.portal.get("news", None))\n+ self.checkAuthenticator("/plone_utils/deleteObjectsByPaths", "paths:list=news")\n+ self.assertFalse(self.portal.get("news", None))\n \n def test_PloneTool_renameObjectsByPaths(self):\n- self.assertFalse(self.portal.get(\'foo\', None))\n+ self.assertFalse(self.portal.get("foo", None))\n self.checkAuthenticator(\n- \'/plone_utils/renameObjectsByPaths\',\n- \'paths:list=events&new_ids:list=foo&new_titles:list=Foo\')\n- self.assertTrue(self.portal.get(\'foo\', None))\n+ "/plone_utils/renameObjectsByPaths",\n+ "paths:list=events&new_ids:list=foo&new_titles:list=Foo",\n+ )\n+ self.assertTrue(self.portal.get("foo", None))\n \n def test_RegistrationTool_editMember(self):\n self.checkAuthenticator(\n- \'/portal_registration/editMember\',\n- \'member_id=%s&password=correct+horse+battery+staple&properties.foo:record=\' % (\n- TEST_USER_ID))\n+ "/portal_registration/editMember",\n+ "member_id=%s&password=correct+horse+battery+staple&properties.foo:record="\n+ % (TEST_USER_ID),\n+ )\n \n def test_MembershipTool_setPassword(self):\n self.checkAuthenticator(\n- \'/portal_membership/setPassword\',\n- \'password=correct+horse+battery+staple\',\n- status=204)\n+ "/portal_membership/setPassword",\n+ "password=correct+horse+battery+staple",\n+ status=204,\n+ )\n \n def test_MembershipTool_deleteMemberArea(self):\n self.checkAuthenticator(\n- \'/portal_membership/deleteMemberArea\',\n- \'member_id=%s\' % TEST_USER_ID)\n+ "/portal_membership/deleteMemberArea", "member_id=%s" % TEST_USER_ID\n+ )\n \n def test_MembershipTool_deleteMembers(self):\n self.checkAuthenticator(\n- \'/portal_membership/deleteMembers\',\n- \'member_ids:list=%s\' % TEST_USER_ID)\n+ "/portal_membership/deleteMembers", "member_ids:list=%s" % TEST_USER_ID\n+ )\n \n def test_userFolderAddUser(self):\n self.checkAuthenticator(\n- \'/acl_users/userFolderAddUser\',\n- \'login=foo&password=bar&domains=&roles:list=Manager\',\n- status=204)\n+ "/acl_users/userFolderAddUser",\n+ "login=foo&password=bar&domains=&roles:list=Manager",\n+ status=204,\n+ )\n \n def test_userFolderEditUser(self):\n self.checkAuthenticator(\n- \'/acl_users/userFolderEditUser\',\n- \'principal_id=%s&password=bar&domains=&roles:list=Manager\'\n- % TEST_USER_ID)\n+ "/acl_users/userFolderEditUser",\n+ "principal_id=%s&password=bar&domains=&roles:list=Manager" % TEST_USER_ID,\n+ )\n \n def test_userFolderDelUsers(self):\n self.checkAuthenticator(\n- \'/acl_users/userFolderDelUsers\',\n- \'names:list=%s\' % TEST_USER_ID,\n- status=204)\n+ "/acl_users/userFolderDelUsers", "names:list=%s" % TEST_USER_ID, status=204\n+ )\ndiff --git a/Products/CMFPlone/tests/testCatalogTool.py b/Products/CMFPlone/tests/testCatalogTool.py\nindex 0027d3996e..6cb9f6ab94 100644\n--- a/Products/CMFPlone/tests/testCatalogTool.py\n+++ b/Products/CMFPlone/tests/testCatalogTool.py\n@@ -28,137 +28,148 @@\n import zope.interface\n \n \n-user2 = \'u2\'\n-group2 = \'g2\'\n+user2 = "u2"\n+group2 = "g2"\n \n-base_content = [\'Members\', \'aggregator\', \'aggregator\',\n- \'events\', \'news\', \'plone\', TEST_USER_ID, \'doc\']\n+base_content = [\n+ "Members",\n+ "aggregator",\n+ "aggregator",\n+ "events",\n+ "news",\n+ "plone",\n+ TEST_USER_ID,\n+ "doc",\n+]\n \n \n class TestCatalogSetup(PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n \n def testSearchableTextIsZCTextIndex(self):\n # SearchableText index should be a ZCTextIndex\n- itype = self.catalog.Indexes[\'SearchableText\'].__class__.__name__\n- self.assertEqual(itype, \'ZCTextIndex\')\n+ itype = self.catalog.Indexes["SearchableText"].__class__.__name__\n+ self.assertEqual(itype, "ZCTextIndex")\n \n def testDescriptionIsZCTextIndex(self):\n # Description index should be a ZCTextIndex\n- itype = self.catalog.Indexes[\'Description\'].__class__.__name__\n- self.assertEqual(itype, \'ZCTextIndex\')\n+ itype = self.catalog.Indexes["Description"].__class__.__name__\n+ self.assertEqual(itype, "ZCTextIndex")\n \n def testTitleIsZCTextIndex(self):\n # Title index should be a ZCTextIndex\n- itype = self.catalog.Indexes[\'Title\'].__class__.__name__\n- self.assertEqual(itype, \'ZCTextIndex\')\n+ itype = self.catalog.Indexes["Title"].__class__.__name__\n+ self.assertEqual(itype, "ZCTextIndex")\n \n def testPloneLexiconIsZCTextLexicon(self):\n # Lexicon should be a ZCTextIndex lexicon\n- self.assertTrue(hasattr(aq_base(self.catalog), \'plone_lexicon\'))\n- self.assertEqual(self.catalog.plone_lexicon.meta_type,\n- \'ZCTextIndex Lexicon\')\n+ self.assertTrue(hasattr(aq_base(self.catalog), "plone_lexicon"))\n+ self.assertEqual(self.catalog.plone_lexicon.meta_type, "ZCTextIndex Lexicon")\n \n def testPathIsExtendedPathIndex(self):\n # path index should be an ExtendedPathIndex\n- self.assertEqual(self.catalog.Indexes[\'path\'].__class__.__name__,\n- \'ExtendedPathIndex\')\n+ self.assertEqual(\n+ self.catalog.Indexes["path"].__class__.__name__, "ExtendedPathIndex"\n+ )\n \n def testGetObjPositionInParentIsGopipIndex(self):\n # getObjPositionInParent index should be a FieldIndex\n # also see TestCatalogOrdering below\n self.assertEqual(\n- self.catalog.Indexes[\'getObjPositionInParent\'].__class__.__name__,\n- \'GopipIndex\')\n+ self.catalog.Indexes["getObjPositionInParent"].__class__.__name__,\n+ "GopipIndex",\n+ )\n \n def testGetObjSizeInSchema(self):\n # getObjSize column should be in catalog schema\n- self.assertTrue(\'getObjSize\' in self.catalog.schema())\n+ self.assertTrue("getObjSize" in self.catalog.schema())\n \n def testExclude_from_navInSchema(self):\n # exclude_from_nav column should be in catalog schema\n- self.assertTrue(\'exclude_from_nav\' in self.catalog.schema())\n+ self.assertTrue("exclude_from_nav" in self.catalog.schema())\n \n def testIs_folderishInSchema(self):\n # is_folderish should be in catalog schema\n- self.assertTrue(\'is_folderish\' in self.catalog.schema())\n+ self.assertTrue("is_folderish" in self.catalog.schema())\n \n def testIs_folderishIsBooleanIndex(self):\n # is_folderish should be a BooleanIndex\n self.assertTrue(\n- self.catalog.Indexes[\'is_folderish\'].__class__.__name__,\n- \'BooleanIndex\')\n+ self.catalog.Indexes["is_folderish"].__class__.__name__, "BooleanIndex"\n+ )\n \n def testDateIsDateIndex(self):\n # Date should be a DateIndex\n- self.assertEqual(self.catalog.Indexes[\'Date\'].__class__.__name__,\n- \'DateIndex\')\n+ self.assertEqual(self.catalog.Indexes["Date"].__class__.__name__, "DateIndex")\n \n def testCreatedIsDateIndex(self):\n # created should be a DateIndex\n- self.assertEqual(self.catalog.Indexes[\'created\'].__class__.__name__,\n- \'DateIndex\')\n+ self.assertEqual(\n+ self.catalog.Indexes["created"].__class__.__name__, "DateIndex"\n+ )\n \n def testEffectiveIsDateIndex(self):\n # effective should be a DateIndex\n- self.assertEqual(self.catalog.Indexes[\'effective\'].__class__.__name__,\n- \'DateIndex\')\n+ self.assertEqual(\n+ self.catalog.Indexes["effective"].__class__.__name__, "DateIndex"\n+ )\n \n def testEndIsDateRecurringIndex(self):\n # end should be a DateRecurringIndex\n- self.assertEqual(self.catalog.Indexes[\'end\'].__class__.__name__,\n- \'DateRecurringIndex\')\n+ self.assertEqual(\n+ self.catalog.Indexes["end"].__class__.__name__, "DateRecurringIndex"\n+ )\n \n def testExpiresIsDateIndex(self):\n # expires should be a DateIndex\n- self.assertEqual(self.catalog.Indexes[\'expires\'].__class__.__name__,\n- \'DateIndex\')\n+ self.assertEqual(\n+ self.catalog.Indexes["expires"].__class__.__name__, "DateIndex"\n+ )\n \n def testModifiedIsDateIndex(self):\n # modified should be a DateIndex\n- self.assertEqual(self.catalog.Indexes[\'modified\'].__class__.__name__,\n- \'DateIndex\')\n+ self.assertEqual(\n+ self.catalog.Indexes["modified"].__class__.__name__, "DateIndex"\n+ )\n \n def testStartIsDateRecurringIndex(self):\n # start should be a DateRecurringIndex\n- self.assertEqual(self.catalog.Indexes[\'start\'].__class__.__name__,\n- \'DateRecurringIndex\')\n+ self.assertEqual(\n+ self.catalog.Indexes["start"].__class__.__name__, "DateRecurringIndex"\n+ )\n \n def testEffectiveRangeIsDateRangeIndex(self):\n # effectiveRange should be a DateRangeIndex\n self.assertEqual(\n- self.catalog.Indexes[\'effectiveRange\'].__class__.__name__,\n- \'DateRangeIndex\')\n+ self.catalog.Indexes["effectiveRange"].__class__.__name__, "DateRangeIndex"\n+ )\n \n def testSortable_TitleIsFieldIndex(self):\n # sortable_title should be a FieldIndex\n self.assertEqual(\n- self.catalog.Indexes[\'sortable_title\'].__class__.__name__,\n- \'FieldIndex\')\n+ self.catalog.Indexes["sortable_title"].__class__.__name__, "FieldIndex"\n+ )\n \n def testExpirationDateInSchema(self):\n # ExpirationDate column should be in catalog schema\n- self.assertTrue(\'ExpirationDate\' in self.catalog.schema())\n+ self.assertTrue("ExpirationDate" in self.catalog.schema())\n \n def testExpiresDateNotInSchema(self):\n # ExpirationDate column should be in catalog schema\n- self.assertFalse(\'ExpiresDate\' in self.catalog.schema())\n+ self.assertFalse("ExpiresDate" in self.catalog.schema())\n \n def testIs_Default_PageIsBooleanIndex(self):\n # is_default_page should be a BooleanIndex\n self.assertEqual(\n- self.catalog.Indexes[\'is_default_page\'].__class__.__name__,\n- \'BooleanIndex\')\n+ self.catalog.Indexes["is_default_page"].__class__.__name__, "BooleanIndex"\n+ )\n \n \n class TestCatalogIndexing(PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n- self.folder.invokeFactory(\'Document\', id=\'doc\',\n- title=\'Foo\', description=\'Bar\')\n+ self.folder.invokeFactory("Document", id="doc", title="Foo", description="Bar")\n self.catalog.unindexObject(self.folder.doc)\n processQueue()\n \n@@ -171,103 +182,102 @@ def assertResults(self, result, expect):\n self.assertEqual(lhs, rhs)\n \n def testFixture(self):\n- self.assertEqual(self.folder.doc.getId(), \'doc\')\n- self.assertEqual(self.folder.doc.Title(), \'Foo\')\n- self.assertEqual(self.folder.doc.Description(), \'Bar\')\n- self.assertEqual(len(self.catalog(getId=\'doc\')), 0)\n- self.assertEqual(len(self.catalog(Title=\'Foo\')), 0)\n- self.assertEqual(len(self.catalog(Description=\'Bar\')), 0)\n+ self.assertEqual(self.folder.doc.getId(), "doc")\n+ self.assertEqual(self.folder.doc.Title(), "Foo")\n+ self.assertEqual(self.folder.doc.Description(), "Bar")\n+ self.assertEqual(len(self.catalog(getId="doc")), 0)\n+ self.assertEqual(len(self.catalog(Title="Foo")), 0)\n+ self.assertEqual(len(self.catalog(Description="Bar")), 0)\n \n def testIndexObject(self):\n # Object should be indexed\n self.catalog.indexObject(self.folder.doc)\n- self.assertEqual(len(self.catalog(getId=\'doc\')), 1)\n- self.assertEqual(len(self.catalog(Title=\'Foo\')), 1)\n- self.assertEqual(len(self.catalog(Description=\'Bar\')), 1)\n+ self.assertEqual(len(self.catalog(getId="doc")), 1)\n+ self.assertEqual(len(self.catalog(Title="Foo")), 1)\n+ self.assertEqual(len(self.catalog(Description="Bar")), 1)\n \n def testReindexObject(self):\n # Object should be indexed\n self.catalog.reindexObject(self.folder.doc)\n- self.assertEqual(len(self.catalog(getId=\'doc\')), 1)\n- self.assertEqual(len(self.catalog(Title=\'Foo\')), 1)\n- self.assertEqual(len(self.catalog(Description=\'Bar\')), 1)\n+ self.assertEqual(len(self.catalog(getId="doc")), 1)\n+ self.assertEqual(len(self.catalog(Title="Foo")), 1)\n+ self.assertEqual(len(self.catalog(Description="Bar")), 1)\n \n def testUnindexObject(self):\n # Object should be unindexed\n self.catalog.indexObject(self.folder.doc)\n- self.assertEqual(len(self.catalog(getId=\'doc\')), 1)\n+ self.assertEqual(len(self.catalog(getId="doc")), 1)\n self.catalog.unindexObject(self.folder.doc)\n- self.assertEqual(len(self.catalog(getId=\'doc\')), 0)\n+ self.assertEqual(len(self.catalog(getId="doc")), 0)\n \n def testIndexObjectUpdatesMetadata(self):\n # Indexing should update metadata\n self.catalog.indexObject(self.folder.doc)\n- brain = self.catalog(getId=\'doc\')[0]\n- self.assertEqual(brain.getId, \'doc\')\n- self.assertEqual(brain.Title, \'Foo\')\n- self.assertEqual(brain.Description, \'Bar\')\n+ brain = self.catalog(getId="doc")[0]\n+ self.assertEqual(brain.getId, "doc")\n+ self.assertEqual(brain.Title, "Foo")\n+ self.assertEqual(brain.Description, "Bar")\n \n def testReindexObjectUpdatesMetadata(self):\n # Reindexing should update metadata\n self.catalog.indexObject(self.folder.doc)\n- self.folder.doc.setTitle(\'Fred\')\n- self.folder.doc.setDescription(\'BamBam\')\n+ self.folder.doc.setTitle("Fred")\n+ self.folder.doc.setDescription("BamBam")\n self.catalog.reindexObject(self.folder.doc)\n- brain = self.catalog(getId=\'doc\')[0]\n- self.assertEqual(brain.getId, \'doc\')\n- self.assertEqual(brain.Title, \'Fred\')\n- self.assertEqual(brain.Description, \'BamBam\')\n+ brain = self.catalog(getId="doc")[0]\n+ self.assertEqual(brain.getId, "doc")\n+ self.assertEqual(brain.Title, "Fred")\n+ self.assertEqual(brain.Description, "BamBam")\n \n def testReindexObjectSkipsMetadata(self):\n # Reindexing should not update metadata when update_metadata=0\n self.catalog.indexObject(self.folder.doc)\n processQueue()\n- self.folder.doc.setTitle(\'Fred\')\n- self.folder.doc.setDescription(\'BamBam\')\n+ self.folder.doc.setTitle("Fred")\n+ self.folder.doc.setDescription("BamBam")\n self.catalog.reindexObject(self.folder.doc, update_metadata=0)\n- brain = self.catalog(getId=\'doc\')[0]\n+ brain = self.catalog(getId="doc")[0]\n # Metadata did not change\n- self.assertEqual(brain.getId, \'doc\')\n- self.assertEqual(brain.Title, \'Foo\')\n- self.assertEqual(brain.Description, \'Bar\')\n+ self.assertEqual(brain.getId, "doc")\n+ self.assertEqual(brain.Title, "Foo")\n+ self.assertEqual(brain.Description, "Bar")\n \n def testReindexTitleOnly(self):\n # Reindexing should only index the Title\n self.catalog.indexObject(self.folder.doc)\n processQueue()\n- self.folder.doc.setTitle(\'Fred\')\n- self.folder.doc.setDescription(\'BamBam\')\n- self.catalog.reindexObject(self.folder.doc, idxs=[\'Title\'])\n- self.assertEqual(len(self.catalog(getId=\'doc\')), 1)\n- self.assertEqual(len(self.catalog(Title=\'Fred\')), 1)\n+ self.folder.doc.setTitle("Fred")\n+ self.folder.doc.setDescription("BamBam")\n+ self.catalog.reindexObject(self.folder.doc, idxs=["Title"])\n+ self.assertEqual(len(self.catalog(getId="doc")), 1)\n+ self.assertEqual(len(self.catalog(Title="Fred")), 1)\n # Description index did not change\n- self.assertEqual(len(self.catalog(Description=\'Bar\')), 1)\n- self.assertEqual(len(self.catalog(Description=\'BamBam\')), 0)\n+ self.assertEqual(len(self.catalog(Description="Bar")), 1)\n+ self.assertEqual(len(self.catalog(Description="BamBam")), 0)\n \n def testReindexTitleOnlyUpdatesMetadata(self):\n # Reindexing Title should update metadata\n self.catalog.indexObject(self.folder.doc)\n- self.folder.doc.setTitle(\'Fred\')\n- self.folder.doc.setDescription(\'BamBam\')\n- self.catalog.reindexObject(self.folder.doc, idxs=[\'Title\'])\n- brain = self.catalog(getId=\'doc\')[0]\n- self.assertEqual(brain.getId, \'doc\')\n- self.assertEqual(brain.Title, \'Fred\')\n- self.assertEqual(brain.Description, \'BamBam\')\n+ self.folder.doc.setTitle("Fred")\n+ self.folder.doc.setDescription("BamBam")\n+ self.catalog.reindexObject(self.folder.doc, idxs=["Title"])\n+ brain = self.catalog(getId="doc")[0]\n+ self.assertEqual(brain.getId, "doc")\n+ self.assertEqual(brain.Title, "Fred")\n+ self.assertEqual(brain.Description, "BamBam")\n \n def testReindexTitleOnlySkipsMetadata(self):\n # Reindexing Title should not update metadata when update_metadata=0\n self.catalog.indexObject(self.folder.doc)\n processQueue()\n- self.folder.doc.setTitle(\'Fred\')\n- self.folder.doc.setDescription(\'BamBam\')\n- self.catalog.reindexObject(self.folder.doc, idxs=[\'Title\'],\n- update_metadata=0)\n- brain = self.catalog(getId=\'doc\')[0]\n+ self.folder.doc.setTitle("Fred")\n+ self.folder.doc.setDescription("BamBam")\n+ self.catalog.reindexObject(self.folder.doc, idxs=["Title"], update_metadata=0)\n+ brain = self.catalog(getId="doc")[0]\n # Metadata did not change\n- self.assertEqual(brain.getId, \'doc\')\n- self.assertEqual(brain.Title, \'Foo\')\n- self.assertEqual(brain.Description, \'Bar\')\n+ self.assertEqual(brain.getId, "doc")\n+ self.assertEqual(brain.Title, "Foo")\n+ self.assertEqual(brain.Description, "Bar")\n \n def testIndexTitleOnly(self):\n # Indexing should only index the Title\n@@ -276,15 +286,15 @@ def testIndexTitleOnly(self):\n # appears to be in the catalog but is not returned\n # by searchResults()!?\n #\n- self.catalog.indexObject(self.folder.doc, idxs=[\'Title\'])\n+ self.catalog.indexObject(self.folder.doc, idxs=["Title"])\n processQueue()\n # The document is cataloged\n path = self.catalog._CatalogTool__url(self.folder.doc)\n self.assertTrue(path in self.catalog._catalog.paths.values())\n # But it is not returned when searching...\n- self.assertEqual(len(self.catalog(getId=\'doc\')), 0)\n- self.assertEqual(len(self.catalog(Title=\'Foo\')), 0) # <-- Should be 1\n- self.assertEqual(len(self.catalog(Description=\'Bar\')), 0)\n+ self.assertEqual(len(self.catalog(getId="doc")), 0)\n+ self.assertEqual(len(self.catalog(Title="Foo")), 0) # <-- Should be 1\n+ self.assertEqual(len(self.catalog(Description="Bar")), 0)\n \n def testIndexIdOnly(self):\n # Indexing should only index the id\n@@ -292,15 +302,15 @@ def testIndexIdOnly(self):\n # TODO: Demonstrate that the behavior is independent\n # of index type.\n #\n- self.catalog.indexObject(self.folder.doc, idxs=[\'getId\'])\n+ self.catalog.indexObject(self.folder.doc, idxs=["getId"])\n processQueue()\n # The document is cataloged\n path = self.catalog._CatalogTool__url(self.folder.doc)\n self.assertTrue(path in self.catalog._catalog.paths.values())\n # But it is not returned when searching...\n- self.assertEqual(len(self.catalog(getId=\'doc\')), 0) # <-- Should be 1\n- self.assertEqual(len(self.catalog(Title=\'Foo\')), 0)\n- self.assertEqual(len(self.catalog(Description=\'Bar\')), 0)\n+ self.assertEqual(len(self.catalog(getId="doc")), 0) # <-- Should be 1\n+ self.assertEqual(len(self.catalog(Title="Foo")), 0)\n+ self.assertEqual(len(self.catalog(Description="Bar")), 0)\n \n def testClearFindAndRebuildRemovesBadContent(self):\n # Index the doc for consistency\n@@ -326,7 +336,7 @@ def testClearFindAndRebuildAddsMissingContent(self):\n # index an object which shouldn\'t be there\n self.catalog.unindexObject(self.portal.Members)\n altered_content = base_content[:]\n- altered_content.remove(\'Members\')\n+ altered_content.remove("Members")\n res = self.catalog.searchResults()\n self.assertResults(res, altered_content)\n self.catalog.clearFindAndRebuild()\n@@ -347,20 +357,19 @@ def testClearFindAndRebuildKeepsModificationDate(self):\n def test_acquired_attributes_are_not_indexed(self):\n # create an index for foo:\n # from Products.PluginIndexes.FieldIndex.FieldIndex import FieldIndex\n- self.catalog.addIndex(\'foo\', \'FieldIndex\')\n+ self.catalog.addIndex("foo", "FieldIndex")\n \n # create attribute foo on folder and index on both, folder and\n # contained\n- self.folder.foo = \'FOO\'\n+ self.folder.foo = "FOO"\n self.catalog.clearFindAndRebuild()\n \n # lets see if we have one result for folder, but nothing for doc:\n- brains = self.catalog(foo=\'FOO\')\n+ brains = self.catalog(foo="FOO")\n self.assertEqual(len(brains), 1)\n \n \n class TestCatalogSearching(PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n self.workflow = self.portal.portal_workflow\n@@ -368,17 +377,16 @@ def afterSetUp(self):\n \n self.portal.acl_users._doAddUser(user2, TEST_USER_PASSWORD, [], [])\n \n- self.folder.invokeFactory(\'Document\', id=\'doc\', text=\'foo\')\n- self.folder.invokeFactory(\'Folder\', id=\'folder2\')\n- self.folder.folder2.invokeFactory(\'Document\', id=\'doc2\', text=\'bar\')\n- self.workflow.doActionFor(self.folder.doc, \'hide\', comment=\'\')\n- self.workflow.doActionFor(self.folder.folder2, \'hide\', comment=\'\')\n- self.workflow.doActionFor(self.folder.folder2.doc2, \'hide\', comment=\'\')\n+ self.folder.invokeFactory("Document", id="doc", text="foo")\n+ self.folder.invokeFactory("Folder", id="folder2")\n+ self.folder.folder2.invokeFactory("Document", id="doc2", text="bar")\n+ self.workflow.doActionFor(self.folder.doc, "hide", comment="")\n+ self.workflow.doActionFor(self.folder.folder2, "hide", comment="")\n+ self.workflow.doActionFor(self.folder.folder2.doc2, "hide", comment="")\n \n # Used for testing AND/OR search functionality below\n- self.folder.invokeFactory(\'Document\', id=\'aaa\', text=\'aaa\',\n- title=\'ccc\')\n- self.folder.invokeFactory(\'Document\', id=\'bbb\', text=\'bbb\')\n+ self.folder.invokeFactory("Document", id="aaa", text="aaa", title="ccc")\n+ self.folder.invokeFactory("Document", id="bbb", text="bbb")\n \n self.setupAuthenticator()\n \n@@ -395,164 +403,199 @@ def testListAllowedRolesAndUsers(self):\n # Should include the group in list of allowed users\n groupname = self.addUser2ToGroup()\n uf = self.portal.acl_users\n- user = f\'user:{groupname:s}\'\n+ user = f"user:{groupname:s}"\n self.assertTrue(\n- user in self.catalog._listAllowedRolesAndUsers(uf.getUser(user2)))\n+ user in self.catalog._listAllowedRolesAndUsers(uf.getUser(user2))\n+ )\n \n def testSearchReturnsDocument(self):\n # Document should be found when owner does a search\n- self.assertEqual(self.catalog(SearchableText=\'aaa\')[0].id, \'aaa\')\n+ self.assertEqual(self.catalog(SearchableText="aaa")[0].id, "aaa")\n \n def testSearchDoesNotReturnDocument(self):\n # Document should not be found when user2 does a search\n self.login(user2)\n- self.assertEqual(len(self.catalog(SearchableText=\'foo\')), 0)\n+ self.assertEqual(len(self.catalog(SearchableText="foo")), 0)\n \n def testSearchReturnsDocumentUsing_DefaultAND(self):\n # Documents should not be found when searching \'aaa bbb\' (which should\n # default to AND)\n- self.assertEqual(len(self.catalog(SearchableText=\'aaa bbb\')), 0)\n- self.assertEqual(len(self.catalog(SearchableText=\'aaa ccc\')), 1)\n+ self.assertEqual(len(self.catalog(SearchableText="aaa bbb")), 0)\n+ self.assertEqual(len(self.catalog(SearchableText="aaa ccc")), 1)\n \n def testSearchReturnsDocumentUsing_AND(self):\n # Documents should not be found when owner does a search using AND\n- self.assertEqual(len(self.catalog(SearchableText=\'aaa AND bbb\')), 0)\n- self.assertEqual(len(self.catalog(SearchableText=\'aaa AND ccc\')), 1)\n+ self.assertEqual(len(self.catalog(SearchableText="aaa AND bbb")), 0)\n+ self.assertEqual(len(self.catalog(SearchableText="aaa AND ccc")), 1)\n \n def testSearchReturnsDocumentUsing_OR(self):\n # Two documents (aaa, bbb) should be found when owner does a search\n # using OR\n- results = self.catalog(SearchableText=\'aaa OR bbb\')\n+ results = self.catalog(SearchableText="aaa OR bbb")\n self.assertEqual(len(results), 2)\n \n def testSearchIgnoresAccents(self):\n # plip 12110\n self.folder.invokeFactory(\n- \'Document\', id=\'docwithaccents1\', description=\'Econom\xc3\xa9trie\')\n+ "Document", id="docwithaccents1", description="Econom\xc3\xa9trie"\n+ )\n self.folder.invokeFactory(\n- \'Document\', id=\'docwithaccents2\', description=\'ECONOMETRIE\')\n+ "Document", id="docwithaccents2", description="ECONOMETRIE"\n+ )\n self.folder.invokeFactory(\n- \'Document\', id=\'docwithaccents3\', description=\'\xc3\xa9conom\xc3\xa9trie\')\n+ "Document", id="docwithaccents3", description="\xc3\xa9conom\xc3\xa9trie"\n+ )\n self.folder.invokeFactory(\n- \'Document\', id=\'docwithaccents4\', description=\'\xc3\x89CONOM\xc3\x89TRIE\')\n+ "Document", id="docwithaccents4", description="\xc3\x89CONOM\xc3\x89TRIE"\n+ )\n \n- self.assertEqual(len(self.catalog(SearchableText=\'econometrie\')), 4)\n- self.assertEqual(len(self.catalog(SearchableText=\'\xc3\xa9conom\xc3\xa9trie\')), 4)\n- self.assertEqual(len(self.catalog(SearchableText=\'Econom\xc3\xa9trie\')), 4)\n- self.assertEqual(len(self.catalog(SearchableText=\'\xc3\x89CONOM\xc3\x89TRIE\')), 4)\n+ self.assertEqual(len(self.catalog(SearchableText="econometrie")), 4)\n+ self.assertEqual(len(self.catalog(SearchableText="\xc3\xa9conom\xc3\xa9trie")), 4)\n+ self.assertEqual(len(self.catalog(SearchableText="Econom\xc3\xa9trie")), 4)\n+ self.assertEqual(len(self.catalog(SearchableText="\xc3\x89CONOM\xc3\x89TRIE")), 4)\n \n- self.assertEqual(len(self.catalog(SearchableText=\'econom?trie\')), 4)\n- self.assertEqual(len(self.catalog(SearchableText=\'econometr*\')), 4)\n+ self.assertEqual(len(self.catalog(SearchableText="econom?trie")), 4)\n+ self.assertEqual(len(self.catalog(SearchableText="econometr*")), 4)\n \n # non-regression with eastern language\n # (use plone.i18n ja normalizer test)\n self.folder.invokeFactory(\n- \'Document\', id=\'docwithjapanchars\', description="\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe3\x83\x9a\xe3\x83\xbc\xe3\x82\xb8")\n+ "Document", id="docwithjapanchars", description="\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe3\x83\x9a\xe3\x83\xbc\xe3\x82\xb8"\n+ )\n self.assertEqual(len(self.catalog(SearchableText="\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88\xe3\x83\x9a\xe3\x83\xbc\xe3\x82\xb8")), 1)\n \n # test with language specific char (fr)\n self.folder.invokeFactory(\n- \'Document\', id=\'docwithfrenchlatinchar\', description=\'\xc5\x93uf\')\n- self.assertEqual(len(self.catalog(SearchableText=\'\xc5\x93uf\')), 1)\n- self.assertEqual(len(self.catalog(SearchableText=\'oeuf\')), 1)\n- self.assertEqual(len(self.catalog(SearchableText=\'\xc5\x92uf\')), 1)\n- self.assertEqual(len(self.catalog(SearchableText=\'OEUF\')), 1)\n- self.assertEqual(len(self.catalog(SearchableText=\'uf\')), 0)\n+ "Document", id="docwithfrenchlatinchar", description="\xc5\x93uf"\n+ )\n+ self.assertEqual(len(self.catalog(SearchableText="\xc5\x93uf")), 1)\n+ self.assertEqual(len(self.catalog(SearchableText="oeuf")), 1)\n+ self.assertEqual(len(self.catalog(SearchableText="\xc5\x92uf")), 1)\n+ self.assertEqual(len(self.catalog(SearchableText="OEUF")), 1)\n+ self.assertEqual(len(self.catalog(SearchableText="uf")), 0)\n \n def testSearchReturnsDocumentWhenPermissionIsTroughLocalRole(self):\n # After adding a group with access rights and containing user2,\n # a search must find the document.\n groupname = self.addUser2ToGroup()\n- sharingView = self.folder.unrestrictedTraverse(\'@@sharing\')\n- sharingView.update_role_settings([{\'id\': groupname,\n- \'type\': \'group\',\n- \'roles\': [\'Owner\']}])\n+ sharingView = self.folder.unrestrictedTraverse("@@sharing")\n+ sharingView.update_role_settings(\n+ [{"id": groupname, "type": "group", "roles": ["Owner"]}]\n+ )\n self.login(user2)\n- self.assertEqual(self.catalog(SearchableText=\'aaa\')[0].id, \'aaa\')\n+ self.assertEqual(self.catalog(SearchableText="aaa")[0].id, "aaa")\n \n def testSearchRespectsLocalRoleAcquisition(self):\n # After adding a group with access rights and containing user2,\n # a search must find the document in subfolders.\n groupname = self.addUser2ToGroup()\n- sharingView = self.folder.unrestrictedTraverse(\'@@sharing\')\n- sharingView.update_role_settings([{\'id\': groupname,\n- \'type\': \'group\',\n- \'roles\': [\'Owner\']}])\n+ sharingView = self.folder.unrestrictedTraverse("@@sharing")\n+ sharingView.update_role_settings(\n+ [{"id": groupname, "type": "group", "roles": ["Owner"]}]\n+ )\n self.login(user2)\n # Local Role works in subfolder\n- self.assertEqual(self.catalog(SearchableText=\'bbb\')[0].id, \'bbb\')\n+ self.assertEqual(self.catalog(SearchableText="bbb")[0].id, "bbb")\n \n def testSearchRespectsLocalRoleAcquisitionDisabled(self):\n # After adding a group with access rights and containing user2,\n # a search should not find documents in subfolders which have\n # disabled local role acquisition.\n groupname = self.addUser2ToGroup()\n- sharingView = self.folder.unrestrictedTraverse(\'@@sharing\')\n- sharingView.update_role_settings([{\'id\': groupname,\n- \'type\': \'group\',\n- \'roles\': [\'Owner\']}])\n+ sharingView = self.folder.unrestrictedTraverse("@@sharing")\n+ sharingView.update_role_settings(\n+ [{"id": groupname, "type": "group", "roles": ["Owner"]}]\n+ )\n # Acquisition off for folder2\n- self.folder.folder2.unrestrictedTraverse(\'@@sharing\') \\\n- .update_inherit(False)\n+ self.folder.folder2.unrestrictedTraverse("@@sharing").update_inherit(False)\n # Everything in subfolder should be invisible\n self.login(user2)\n- self.assertFalse(self.catalog(SearchableText=\'bar\'))\n+ self.assertFalse(self.catalog(SearchableText="bar"))\n \n def testSearchIgnoreAccents(self):\n- """PLIP 12110\n- """\n+ """PLIP 12110"""\n self.folder.invokeFactory(\n- \'Document\',\n- id=\'docwithaccents-1\',\n- text=RichTextValue(\'Econom\xc3\xa9trie\', \'text/html\', \'text/x-html-safe\'),\n- title=\'foo\')\n+ "Document",\n+ id="docwithaccents-1",\n+ text=RichTextValue("Econom\xc3\xa9trie", "text/html", "text/x-html-safe"),\n+ title="foo",\n+ )\n self.folder.invokeFactory(\n- \'Document\',\n- id=\'docwithaccents-2\',\n- text=RichTextValue(\'\xc3\x89conom\xc3\xa9trie\', \'text/html\', \'text/x-html-safe\'))\n+ "Document",\n+ id="docwithaccents-2",\n+ text=RichTextValue("\xc3\x89conom\xc3\xa9trie", "text/html", "text/x-html-safe"),\n+ )\n self.folder.invokeFactory(\n- \'Document\',\n- id=\'docwithout-accents\',\n- text=RichTextValue(\'ECONOMETRIE\', \'text/html\', \'text/x-html-safe\'))\n+ "Document",\n+ id="docwithout-accents",\n+ text=RichTextValue("ECONOMETRIE", "text/html", "text/x-html-safe"),\n+ )\n \n- self.assertEqual(len(self.catalog(SearchableText=\'\xc3\x89conom\xc3\xa9trie\')), 3)\n- self.assertEqual(len(self.catalog(SearchableText=\'Econom\xc3\xa9trie\')), 3)\n- self.assertEqual(len(self.catalog(SearchableText=\'ECONOMETRIE\')), 3)\n+ self.assertEqual(len(self.catalog(SearchableText="\xc3\x89conom\xc3\xa9trie")), 3)\n+ self.assertEqual(len(self.catalog(SearchableText="Econom\xc3\xa9trie")), 3)\n+ self.assertEqual(len(self.catalog(SearchableText="ECONOMETRIE")), 3)\n \n def testSearchIsProtected(self):\n self.login()\n self.folder.invokeFactory("Document", "sekretz")\n self.logout()\n catalog = self.portal.portal_catalog\n- bogus = catalog.search({\'portal_type\': \'Document\'})\n- real = catalog.portal_catalog.searchResults(portal_type=\'Document\')\n+ bogus = catalog.search({"portal_type": "Document"})\n+ real = catalog.portal_catalog.searchResults(portal_type="Document")\n self.assertEqual(len(bogus), len(real))\n \n \n class TestCatalogSorting(PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n \n- self.folder.invokeFactory(\'Document\', id=\'doc\', text=RichTextValue(\'foo\', \'text/html\', \'text/x-html-safe\'))\n- self.folder.doc.setTitle(\'12 Document 25\')\n- self.folder.invokeFactory(\'Document\', id=\'doc2\', text=RichTextValue(\'foo\', \'text/html\', \'text/x-html-safe\'))\n- self.folder.doc2.setTitle(\'3 Document 4\')\n- self.folder.invokeFactory(\'Document\', id=\'doc3\', text=RichTextValue(\'foo\', \'text/html\', \'text/x-html-safe\'))\n- self.folder.doc3.setTitle(\'12 Document 4\')\n+ self.folder.invokeFactory(\n+ "Document",\n+ id="doc",\n+ text=RichTextValue("foo", "text/html", "text/x-html-safe"),\n+ )\n+ self.folder.doc.setTitle("12 Document 25")\n+ self.folder.invokeFactory(\n+ "Document",\n+ id="doc2",\n+ text=RichTextValue("foo", "text/html", "text/x-html-safe"),\n+ )\n+ self.folder.doc2.setTitle("3 Document 4")\n+ self.folder.invokeFactory(\n+ "Document",\n+ id="doc3",\n+ text=RichTextValue("foo", "text/html", "text/x-html-safe"),\n+ )\n+ self.folder.doc3.setTitle("12 Document 4")\n \n- self.folder.invokeFactory(\'Document\', id=\'doc4\', text=RichTextValue(\'bar\', \'text/html\', \'text/x-html-safe\'))\n- self.folder.doc4.setTitle(\'document 12\')\n- self.folder.invokeFactory(\'Document\', id=\'doc5\', text=RichTextValue(\'bar\', \'text/html\', \'text/x-html-safe\'))\n- self.folder.doc5.setTitle(\'Document 2\')\n- self.folder.invokeFactory(\'Document\', id=\'doc6\', text=RichTextValue(\'bar\', \'text/html\', \'text/x-html-safe\'))\n- self.folder.doc6.setTitle(\'DOCUMENT 4\')\n+ self.folder.invokeFactory(\n+ "Document",\n+ id="doc4",\n+ text=RichTextValue("bar", "text/html", "text/x-html-safe"),\n+ )\n+ self.folder.doc4.setTitle("document 12")\n+ self.folder.invokeFactory(\n+ "Document",\n+ id="doc5",\n+ text=RichTextValue("bar", "text/html", "text/x-html-safe"),\n+ )\n+ self.folder.doc5.setTitle("Document 2")\n+ self.folder.invokeFactory(\n+ "Document",\n+ id="doc6",\n+ text=RichTextValue("bar", "text/html", "text/x-html-safe"),\n+ )\n+ self.folder.doc6.setTitle("DOCUMENT 4")\n \n- self.folder.invokeFactory(\'Document\', id="doc7")\n- self.folder.doc7.setTitle(\'Long titles used to be truncated, but we changed this, see issue 3690. 0002\')\n+ self.folder.invokeFactory("Document", id="doc7")\n+ self.folder.doc7.setTitle(\n+ "Long titles used to be truncated, but we changed this, see issue 3690. 0002"\n+ )\n \n- self.folder.invokeFactory(\'Document\', id="doc8")\n- self.folder.doc8.setTitle(\'Long titles used to be truncated, but we changed this, see issue 3690. 0001\')\n+ self.folder.invokeFactory("Document", id="doc8")\n+ self.folder.doc8.setTitle(\n+ "Long titles used to be truncated, but we changed this, see issue 3690. 0001"\n+ )\n \n self.folder.doc.reindexObject()\n self.folder.doc2.reindexObject()\n@@ -564,114 +607,116 @@ def afterSetUp(self):\n self.folder.doc8.reindexObject()\n \n def testSortMultipleColumns(self):\n- path = \'/\'.join(self.folder.getPhysicalPath())\n+ path = "/".join(self.folder.getPhysicalPath())\n query = partial(self.catalog, path=path)\n- brains = query(sort_on=[\'portal_type\', \'sortable_title\'])\n+ brains = query(sort_on=["portal_type", "sortable_title"])\n self.assertListEqual(\n [brain.getPath() for brain in brains],\n [\n- \'/plone/Members/test_user_1_/doc2\',\n- \'/plone/Members/test_user_1_/doc3\',\n- \'/plone/Members/test_user_1_/doc\',\n- \'/plone/Members/test_user_1_/doc5\',\n- \'/plone/Members/test_user_1_/doc6\',\n- \'/plone/Members/test_user_1_/doc4\',\n- \'/plone/Members/test_user_1_/doc8\',\n- \'/plone/Members/test_user_1_/doc7\',\n- \'/plone/Members/test_user_1_\'\n+ "/plone/Members/test_user_1_/doc2",\n+ "/plone/Members/test_user_1_/doc3",\n+ "/plone/Members/test_user_1_/doc",\n+ "/plone/Members/test_user_1_/doc5",\n+ "/plone/Members/test_user_1_/doc6",\n+ "/plone/Members/test_user_1_/doc4",\n+ "/plone/Members/test_user_1_/doc8",\n+ "/plone/Members/test_user_1_/doc7",\n+ "/plone/Members/test_user_1_",\n ],\n )\n- brains = query(sort_on=[\'portal_type\', \'getId\'])\n+ brains = query(sort_on=["portal_type", "getId"])\n self.assertListEqual(\n [brain.getPath() for brain in brains],\n [\n- \'/plone/Members/test_user_1_/doc\',\n- \'/plone/Members/test_user_1_/doc2\',\n- \'/plone/Members/test_user_1_/doc3\',\n- \'/plone/Members/test_user_1_/doc4\',\n- \'/plone/Members/test_user_1_/doc5\',\n- \'/plone/Members/test_user_1_/doc6\',\n- \'/plone/Members/test_user_1_/doc7\',\n- \'/plone/Members/test_user_1_/doc8\',\n- \'/plone/Members/test_user_1_\',\n- ]\n+ "/plone/Members/test_user_1_/doc",\n+ "/plone/Members/test_user_1_/doc2",\n+ "/plone/Members/test_user_1_/doc3",\n+ "/plone/Members/test_user_1_/doc4",\n+ "/plone/Members/test_user_1_/doc5",\n+ "/plone/Members/test_user_1_/doc6",\n+ "/plone/Members/test_user_1_/doc7",\n+ "/plone/Members/test_user_1_/doc8",\n+ "/plone/Members/test_user_1_",\n+ ],\n )\n \n def testUnknownSortOnIsIgnored(self):\n # You should not get a CatalogError when an invalid sort_on is passed.\n # I get crazy sort_ons like \'194\' or \'null\'.\n- self.assertTrue(len(\n- self.catalog(SearchableText=\'foo\', sort_on=\'194\')) > 0)\n- self.assertTrue(len(\n- self.catalog(SearchableText=\'foo\', sort_on=\'null\')) > 0)\n- self.assertTrue(len(\n- self.catalog(SearchableText=\'foo\', sort_on=\'relevance\')) > 0)\n+ self.assertTrue(len(self.catalog(SearchableText="foo", sort_on="194")) > 0)\n+ self.assertTrue(len(self.catalog(SearchableText="foo", sort_on="null")) > 0)\n+ self.assertTrue(\n+ len(self.catalog(SearchableText="foo", sort_on="relevance")) > 0\n+ )\n \n def testSortTitleReturnsProperOrderForNumbers(self):\n # Documents should be returned in proper numeric order\n- results = self.catalog(SearchableText=\'foo\', sort_on=\'sortable_title\')\n- self.assertEqual(results[0].getId, \'doc2\')\n- self.assertEqual(results[1].getId, \'doc3\')\n- self.assertEqual(results[2].getId, \'doc\')\n+ results = self.catalog(SearchableText="foo", sort_on="sortable_title")\n+ self.assertEqual(results[0].getId, "doc2")\n+ self.assertEqual(results[1].getId, "doc3")\n+ self.assertEqual(results[2].getId, "doc")\n \n def testSortTitleIgnoresCase(self):\n # Documents should be returned in case insensitive order\n- results = self.catalog(SearchableText=\'bar\', sort_on=\'sortable_title\')\n- self.assertEqual(results[0].getId, \'doc5\')\n- self.assertEqual(results[1].getId, \'doc6\')\n- self.assertEqual(results[2].getId, \'doc4\')\n+ results = self.catalog(SearchableText="bar", sort_on="sortable_title")\n+ self.assertEqual(results[0].getId, "doc5")\n+ self.assertEqual(results[1].getId, "doc6")\n+ self.assertEqual(results[2].getId, "doc4")\n \n def testSortableTitleOutput(self):\n doc = self.folder.doc\n wrapped = IndexableObjectWrapper(doc, self.portal.portal_catalog)\n \n- self.assertEqual(wrapped.sortable_title, \'0012 document 0025\')\n+ self.assertEqual(wrapped.sortable_title, "0012 document 0025")\n \n def testSortableTitleInLongTitles(self):\n doc = self.folder.doc7\n wrapped = IndexableObjectWrapper(doc, self.portal.portal_catalog)\n \n- self.assertEqual(wrapped.sortable_title, \'long titles used to be truncated, but we changed this, see issue 3690. 0002\')\n-\n+ self.assertEqual(\n+ wrapped.sortable_title,\n+ "long titles used to be truncated, but we changed this, see issue 3690. 0002",\n+ )\n \n def testSortableNonASCIITitles(self):\n # test a utf-8 encoded string gets properly unicode converted\n # sort must ignore accents\n- title = b\'La Pe\\xc3\\xb1a\'\n+ title = b"La Pe\\xc3\\xb1a"\n doc = self.folder.doc\n- doc.title = title.decode(\'utf-8\')\n+ doc.title = title.decode("utf-8")\n wrapped = IndexableObjectWrapper(doc, self.portal.portal_catalog)\n- self.assertEqual(wrapped.sortable_title, \'la pena\')\n+ self.assertEqual(wrapped.sortable_title, "la pena")\n \n def testSortableDate(self):\n- title = \'2012-06-01 foo document\'\n+ title = "2012-06-01 foo document"\n doc = self.folder.doc\n doc.setTitle(title)\n wrapped = IndexableObjectWrapper(doc, self.portal.portal_catalog)\n- self.assertEqual(wrapped.sortable_title,\n- \'2012-0006-0001 foo document\')\n+ self.assertEqual(wrapped.sortable_title, "2012-0006-0001 foo document")\n \n def testSortableLongNumberPrefix(self):\n- title = \'1.2.3 foo document\'\n+ title = "1.2.3 foo document"\n doc = self.folder.doc\n doc.setTitle(title)\n wrapped = IndexableObjectWrapper(doc, self.portal.portal_catalog)\n- self.assertEqual(wrapped.sortable_title,\n- \'0001.0002.0003 foo document\')\n- title = \'1.2.3 foo program\'\n+ self.assertEqual(wrapped.sortable_title, "0001.0002.0003 foo document")\n+ title = "1.2.3 foo program"\n doc.setTitle(title)\n wrapped = IndexableObjectWrapper(doc, self.portal.portal_catalog)\n- self.assertEqual(wrapped.sortable_title,\n- \'0001.0002.0003 foo program\')\n+ self.assertEqual(wrapped.sortable_title, "0001.0002.0003 foo program")\n \n def testSortableLongCommonPrefix(self):\n- title = \'some documents have too long a name and only differ at \' \\\n- \'the very end - like 1.jpeg\'\n+ title = (\n+ "some documents have too long a name and only differ at "\n+ "the very end - like 1.jpeg"\n+ )\n doc = self.folder.doc\n doc.setTitle(title)\n wrapped = IndexableObjectWrapper(doc, self.portal.portal_catalog)\n- self.assertEqual(wrapped.sortable_title,\n- \'some documents have too long a name and only differ at the very end - like 0001.jpeg\')\n+ self.assertEqual(\n+ wrapped.sortable_title,\n+ "some documents have too long a name and only differ at the very end - like 0001.jpeg",\n+ )\n \n \n class TestFolderCataloging(PloneTestCase):\n@@ -680,181 +725,182 @@ class TestFolderCataloging(PloneTestCase):\n \n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n- self.folder.invokeFactory(\'Folder\', id=\'foo\')\n+ self.folder.invokeFactory("Folder", id="foo")\n self.setupAuthenticator()\n \n # z3c.form needs IFormLayer provided by request\n alsoProvides(self.folder.REQUEST, IFormLayer)\n \n def testFolderTitleIsUpdatedOnFolderTitleChange(self):\n- title = \'Test Folder - Snooze!\'\n+ title = "Test Folder - Snooze!"\n \n self.folder.REQUEST.form = {\n- \'form.widgets.new_id\': \'foo\',\n- \'form.widgets.new_title\': title,\n+ "form.widgets.new_id": "foo",\n+ "form.widgets.new_title": title,\n }\n- form = self.folder.restrictedTraverse(\'@@folder_rename\')\n+ form = self.folder.restrictedTraverse("@@folder_rename")\n form.update()\n \n self.loginAsPortalOwner()\n- button = form.buttons[\'Rename\']\n+ button = form.buttons["Rename"]\n form.handlers.getHandler(button)(form, button)\n \n- results = self.catalog(Title=\'Snooze\')\n+ results = self.catalog(Title="Snooze")\n self.assertTrue(results)\n for result in results:\n self.assertEqual(result.Title, title)\n- self.assertEqual(result.getId, \'foo\')\n+ self.assertEqual(result.getId, "foo")\n \n def testFolderTitleIsUpdatedOnFolderRename(self):\n- title = \'Test Folder - Snooze!\'\n+ title = "Test Folder - Snooze!"\n \n self.folder.REQUEST.form = {\n- \'form.widgets.new_id\': \'bar\',\n- \'form.widgets.new_title\': title,\n+ "form.widgets.new_id": "bar",\n+ "form.widgets.new_title": title,\n }\n- form = self.folder.restrictedTraverse(\'@@folder_rename\')\n+ form = self.folder.restrictedTraverse("@@folder_rename")\n form.update()\n \n self.loginAsPortalOwner()\n- button = form.buttons[\'Rename\']\n+ button = form.buttons["Rename"]\n form.handlers.getHandler(button)(form, button)\n \n- results = self.catalog(Title=\'Snooze\')\n+ results = self.catalog(Title="Snooze")\n self.assertTrue(results)\n for result in results:\n self.assertEqual(result.Title, title)\n- self.assertEqual(result.getId, \'bar\')\n+ self.assertEqual(result.getId, "bar")\n \n def testSetTitleDoesNotUpdateCatalog(self):\n # setTitle() should not update the catalog\n- title = \'Test Folder - Snooze!\'\n- self.assertTrue(self.catalog(getId=\'foo\'))\n+ title = "Test Folder - Snooze!"\n+ self.assertTrue(self.catalog(getId="foo"))\n self.folder.foo.setTitle(title)\n # Title is a TextIndex\n- self.assertFalse(self.catalog(Title=\'Snooze\'))\n+ self.assertFalse(self.catalog(Title="Snooze"))\n \n \n class TestCatalogOrdering(PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n- self.folder.invokeFactory(\n- \'Document\', id=\'doc1\', text=\'foo\', title=\'First\')\n- self.folder.invokeFactory(\n- \'Document\', id=\'doc2\', text=\'bar\', title=\'Second\')\n- self.folder.invokeFactory(\n- \'Document\', id=\'doc3\', text=\'bloo\', title=\'Third\')\n- self.folder.invokeFactory(\n- \'Document\', id=\'doc4\', text=\'blee\', title=\'Fourth\')\n+ self.folder.invokeFactory("Document", id="doc1", text="foo", title="First")\n+ self.folder.invokeFactory("Document", id="doc2", text="bar", title="Second")\n+ self.folder.invokeFactory("Document", id="doc3", text="bloo", title="Third")\n+ self.folder.invokeFactory("Document", id="doc4", text="blee", title="Fourth")\n \n def testInitialOrder(self):\n- self.assertEqual(self.folder.getObjectPosition(\'doc1\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'doc2\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'doc3\'), 2)\n- self.assertEqual(self.folder.getObjectPosition(\'doc4\'), 3)\n+ self.assertEqual(self.folder.getObjectPosition("doc1"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("doc2"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("doc3"), 2)\n+ self.assertEqual(self.folder.getObjectPosition("doc4"), 3)\n \n def testOrderIsUnchangedOnDefaultFolderPosition(self):\n # Calling the folder_position script with no arguments should\n # give no complaints and have no effect.\n folder_position(self.folder)\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\')\n- expected = [\'doc1\', \'doc2\', \'doc3\', \'doc4\']\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n+ )\n+ expected = ["doc1", "doc2", "doc3", "doc4"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsUpdatedOnMoveDown(self):\n- folder_position(self.folder, \'down\', \'doc1\')\n+ folder_position(self.folder, "down", "doc1")\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\',\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n )\n- expected = [\'doc2\', \'doc1\', \'doc3\', \'doc4\']\n+ expected = ["doc2", "doc1", "doc3", "doc4"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsUpdatedOnMoveUp(self):\n- folder_position(self.folder, \'up\', \'doc3\')\n+ folder_position(self.folder, "up", "doc3")\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\',\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n )\n- expected = [\'doc1\', \'doc3\', \'doc2\', \'doc4\']\n+ expected = ["doc1", "doc3", "doc2", "doc4"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsUpdatedOnMoveTop(self):\n- folder_position(self.folder, \'top\', \'doc3\')\n+ folder_position(self.folder, "top", "doc3")\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\'\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n )\n- expected = [\'doc3\', \'doc1\', \'doc2\', \'doc4\']\n+ expected = ["doc3", "doc1", "doc2", "doc4"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsUpdatedOnMoveBottom(self):\n- folder_position(self.folder, \'bottom\', \'doc3\')\n+ folder_position(self.folder, "bottom", "doc3")\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\'\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n )\n- expected = [\'doc1\', \'doc2\', \'doc4\', \'doc3\']\n+ expected = ["doc1", "doc2", "doc4", "doc3"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsUpdatedOnSort(self):\n- folder_position(self.folder, position=\'ordered\', id=\'Title\')\n+ folder_position(self.folder, position="ordered", id="Title")\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\')\n- expected = [\'doc1\', \'doc4\', \'doc2\', \'doc3\']\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n+ )\n+ expected = ["doc1", "doc4", "doc2", "doc3"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsUpdatedOnReverse(self):\n- folder_position(self.folder, position=\'ordered\',\n- id=\'Title\', reverse=True)\n+ folder_position(self.folder, position="ordered", id="Title", reverse=True)\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\')\n- expected = [\'doc3\', \'doc2\', \'doc4\', \'doc1\']\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n+ )\n+ expected = ["doc3", "doc2", "doc4", "doc1"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsUpdatedOnSimpleReverse(self):\n- folder_position(self.folder, position=\'ordered\', reverse=True)\n+ folder_position(self.folder, position="ordered", reverse=True)\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\')\n- expected = [\'doc4\', \'doc3\', \'doc2\', \'doc1\']\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n+ )\n+ expected = ["doc4", "doc3", "doc2", "doc1"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsFineWithObjectCreation(self):\n- self.folder.invokeFactory(\'Document\', id=\'doc5\', text=\'blam\')\n+ self.folder.invokeFactory("Document", id="doc5", text="blam")\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\'\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n )\n- expected = [\'doc1\', \'doc2\', \'doc3\', \'doc4\', \'doc5\']\n+ expected = ["doc1", "doc2", "doc3", "doc4", "doc5"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsFineWithObjectDeletion(self):\n- self.folder.manage_delObjects([\'doc3\', ])\n+ self.folder.manage_delObjects(\n+ [\n+ "doc3",\n+ ]\n+ )\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\'\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n )\n- expected = [\'doc1\', \'doc2\', \'doc4\']\n+ expected = ["doc1", "doc2", "doc4"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderIsFineWithObjectRenaming(self):\n-\n # I don\'t know why this is failing. manage_renameObjects throws an\n # error that blames permissions or lack of support by the obj. The\n # obj is a # Plone Document, and the owner of doc2 is portal_owner.\n@@ -862,40 +908,40 @@ def testOrderIsFineWithObjectRenaming(self):\n \n transaction.savepoint(optimistic=True)\n \n- self.folder.manage_renameObjects([\'doc2\'], [\'buzz\'])\n+ self.folder.manage_renameObjects(["doc2"], ["buzz"])\n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\'\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n )\n- expected = [\'doc1\', \'buzz\', \'doc3\', \'doc4\']\n+ expected = ["doc1", "buzz", "doc3", "doc4"]\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n def testOrderAfterALotOfChanges(self):\n # [\'doc1\',\'doc2\',\'doc3\',\'doc4\']\n \n- folder_position(self.folder, \'down\', \'doc1\')\n- folder_position(self.folder, \'down\', \'doc1\')\n+ folder_position(self.folder, "down", "doc1")\n+ folder_position(self.folder, "down", "doc1")\n # [\'doc2\',\'doc3\',\'doc1\',\'doc4\']\n \n- folder_position(self.folder, \'top\', \'doc3\')\n+ folder_position(self.folder, "top", "doc3")\n # [\'doc3\',\'doc2\',\'doc1\',\'doc4\']\n \n- self.folder.invokeFactory(\'Document\', id=\'doc5\', text=\'blam\')\n- self.folder.invokeFactory(\'Document\', id=\'doc6\', text=\'blam\')\n- self.folder.invokeFactory(\'Document\', id=\'doc7\', text=\'blam\')\n- self.folder.invokeFactory(\'Document\', id=\'doc8\', text=\'blam\')\n+ self.folder.invokeFactory("Document", id="doc5", text="blam")\n+ self.folder.invokeFactory("Document", id="doc6", text="blam")\n+ self.folder.invokeFactory("Document", id="doc7", text="blam")\n+ self.folder.invokeFactory("Document", id="doc8", text="blam")\n # [\'doc3\',\'doc2\',\'doc1\',\'doc4\',\'doc5\',\'doc6\',\'doc7\',\'doc8\',]\n \n- #self.folder.manage_renameObjects(\'Document\', id=\'doc5\', text=\'blam\')\n+ # self.folder.manage_renameObjects(\'Document\', id=\'doc5\', text=\'blam\')\n \n- self.folder.manage_delObjects([\'doc3\', \'doc4\', \'doc5\', \'doc7\'])\n- expected = [\'doc2\', \'doc1\', \'doc6\', \'doc8\']\n+ self.folder.manage_delObjects(["doc3", "doc4", "doc5", "doc7"])\n+ expected = ["doc2", "doc1", "doc6", "doc8"]\n \n folder_docs = self.catalog(\n- portal_type=\'Document\',\n- path=\'/\'.join(self.folder.getPhysicalPath()),\n- sort_on=\'getObjPositionInParent\',\n+ portal_type="Document",\n+ path="/".join(self.folder.getPhysicalPath()),\n+ sort_on="getObjPositionInParent",\n )\n self.assertEqual([b.getId for b in folder_docs], expected)\n \n@@ -904,28 +950,28 @@ def testAllObjectsHaveOrder(self):\n # returns the same number of results as one without, make sure\n # the Members folder is in the catalog and has getObjPositionInParent\n all_objs = self.catalog()\n- sorted_objs = self.catalog(sort_on=\'getObjPositionInParent\')\n+ sorted_objs = self.catalog(sort_on="getObjPositionInParent")\n self.assertEqual(len(all_objs), len(sorted_objs))\n \n members = self.portal.Members\n- members_path = \'/\'.join(members.getPhysicalPath())\n+ members_path = "/".join(members.getPhysicalPath())\n members_query = self.catalog(path=members_path)\n members_sorted = self.catalog(\n path=members_path,\n- sort_on=\'getObjPositionInParent\',\n+ sort_on="getObjPositionInParent",\n )\n self.assertTrue(len(members_query))\n self.assertEqual(len(members_query), len(members_sorted))\n \n def testGopipIndexer(self):\n from Products.CMFPlone.CatalogTool import getObjPositionInParent\n+\n get_pos = getObjPositionInParent.callable\n self.assertEqual(get_pos(self.folder.doc1), 0)\n self.assertEqual(get_pos(self.folder.doc4), 3)\n \n \n class TestCatalogBugs(PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n # Make the catalog tool paste-able\n@@ -938,21 +984,21 @@ def afterClear(self):\n def testCanPasteCatalog(self):\n # Should be able to copy/paste a portal_catalog. Triggers\n # manage_afterAdd of portal_catalog thereby exposing another bug :-/\n- self.setRoles([\'Manager\'])\n- cb = self.portal.manage_copyObjects([\'portal_catalog\'])\n+ self.setRoles(["Manager"])\n+ cb = self.portal.manage_copyObjects(["portal_catalog"])\n self.folder.manage_pasteObjects(cb)\n- self.assertTrue(hasattr(aq_base(self.folder), \'portal_catalog\'))\n+ self.assertTrue(hasattr(aq_base(self.folder), "portal_catalog"))\n \n def testPastingCatalogPreservesTextIndexes(self):\n # Pasting the catalog should not cause indexes to be removed.\n- self.setRoles([\'Manager\'])\n- cb = self.portal.manage_copyObjects([\'portal_catalog\'])\n+ self.setRoles(["Manager"])\n+ cb = self.portal.manage_copyObjects(["portal_catalog"])\n self.folder.manage_pasteObjects(cb)\n- self.assertTrue(hasattr(aq_base(self.folder), \'portal_catalog\'))\n+ self.assertTrue(hasattr(aq_base(self.folder), "portal_catalog"))\n cat = self.folder.portal_catalog\n- self.assertTrue(\'SearchableText\' in cat.indexes())\n+ self.assertTrue("SearchableText" in cat.indexes())\n # CMF added lexicons should stick around too\n- self.assertTrue(hasattr(aq_base(cat), \'plaintext_lexicon\'))\n+ self.assertTrue(hasattr(aq_base(cat), "plaintext_lexicon"))\n \n \n class TestCatalogUnindexing(PloneTestCase):\n@@ -962,88 +1008,87 @@ class TestCatalogUnindexing(PloneTestCase):\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n self.workflow = self.portal.portal_workflow\n- self.folder.invokeFactory(\'Document\', id=\'doc\')\n+ self.folder.invokeFactory("Document", id="doc")\n self.setupAuthenticator()\n \n def testVisibleIsDefault(self):\n- state = self.workflow.getInfoFor(self.folder.doc, \'review_state\')\n- self.assertEqual(state, \'visible\')\n+ state = self.workflow.getInfoFor(self.folder.doc, "review_state")\n+ self.assertEqual(state, "visible")\n \n def testVisibleCanBeFound(self):\n- self.assertTrue(self.catalog(getId=\'doc\'))\n+ self.assertTrue(self.catalog(getId="doc"))\n \n def testVisibleIsUnindexed(self):\n- self.folder._delObject(\'doc\')\n- self.assertFalse(self.catalog(getId=\'doc\'))\n+ self.folder._delObject("doc")\n+ self.assertFalse(self.catalog(getId="doc"))\n \n def testPrivateCanBeFound(self):\n- self.workflow.doActionFor(self.folder.doc, \'hide\')\n- self.assertTrue(self.catalog(getId=\'doc\'))\n+ self.workflow.doActionFor(self.folder.doc, "hide")\n+ self.assertTrue(self.catalog(getId="doc"))\n \n def testPrivateIsUnindexed(self):\n- self.workflow.doActionFor(self.folder.doc, \'hide\')\n- self.folder._delObject(\'doc\')\n- self.assertFalse(self.catalog(getId=\'doc\'))\n+ self.workflow.doActionFor(self.folder.doc, "hide")\n+ self.folder._delObject("doc")\n+ self.assertFalse(self.catalog(getId="doc"))\n \n def testPendingCanBeFound(self):\n- self.workflow.doActionFor(self.folder.doc, \'submit\')\n- self.assertTrue(self.catalog(getId=\'doc\'))\n+ self.workflow.doActionFor(self.folder.doc, "submit")\n+ self.assertTrue(self.catalog(getId="doc"))\n \n def testPendingIsUnindexed(self):\n- self.workflow.doActionFor(self.folder.doc, \'submit\')\n- self.folder._delObject(\'doc\')\n- self.assertFalse(self.catalog(getId=\'doc\'))\n+ self.workflow.doActionFor(self.folder.doc, "submit")\n+ self.folder._delObject("doc")\n+ self.assertFalse(self.catalog(getId="doc"))\n \n def testPublishedCanBeFound(self):\n- self.setRoles([\'Manager\'])\n- self.workflow.doActionFor(self.folder.doc, \'publish\')\n- self.assertTrue(self.catalog(getId=\'doc\'))\n+ self.setRoles(["Manager"])\n+ self.workflow.doActionFor(self.folder.doc, "publish")\n+ self.assertTrue(self.catalog(getId="doc"))\n \n def testPublishedIsUnindexed(self):\n- self.setRoles([\'Manager\'])\n- self.workflow.doActionFor(self.folder.doc, \'publish\')\n- self.folder._delObject(\'doc\')\n- self.assertFalse(self.catalog(getId=\'doc\'))\n+ self.setRoles(["Manager"])\n+ self.workflow.doActionFor(self.folder.doc, "publish")\n+ self.folder._delObject("doc")\n+ self.assertFalse(self.catalog(getId="doc"))\n \n def testPublishedIsUnindexedIfOwnerDeletes(self):\n- self.setRoles([\'Manager\'])\n- self.workflow.doActionFor(self.folder.doc, \'publish\')\n- self.setRoles([\'Member\'])\n- self.folder._delObject(\'doc\')\n- self.assertFalse(self.catalog(getId=\'doc\'))\n+ self.setRoles(["Manager"])\n+ self.workflow.doActionFor(self.folder.doc, "publish")\n+ self.setRoles(["Member"])\n+ self.folder._delObject("doc")\n+ self.assertFalse(self.catalog(getId="doc"))\n \n def testPublishedIsUnindexedByFolderDeleteScript(self):\n doc = self.folder.doc\n- self.setRoles([\'Manager\'])\n- self.workflow.doActionFor(doc, \'publish\')\n- self.setRoles([\'Member\'])\n+ self.setRoles(["Manager"])\n+ self.workflow.doActionFor(doc, "publish")\n+ self.setRoles(["Member"])\n alsoProvides(doc.REQUEST, IFormLayer)\n- doc.restrictedTraverse(\'@@object_delete\')()\n- self.assertFalse(self.catalog(getId=\'doc\'))\n+ doc.restrictedTraverse("@@object_delete")()\n+ self.assertFalse(self.catalog(getId="doc"))\n \n def testPublishedIsUnindexedWhenDeletingParentFolder(self):\n # Works here too!\n- self.setRoles([\'Manager\'])\n- self.workflow.doActionFor(self.folder.doc, \'publish\')\n- self.setRoles([\'Member\'])\n+ self.setRoles(["Manager"])\n+ self.workflow.doActionFor(self.folder.doc, "publish")\n+ self.setRoles(["Member"])\n self.folder.aq_parent._delObject(self.folder.getId())\n- self.assertFalse(self.catalog(getId=\'doc\'))\n+ self.assertFalse(self.catalog(getId="doc"))\n \n \n class TestCatalogExpirationFiltering(PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n- self.folder.invokeFactory(\'Document\', id=\'doc\')\n+ self.folder.invokeFactory("Document", id="doc")\n \n # Create unprivileged user\n- self.portal.acl_users._doAddUser(user2, TEST_USER_PASSWORD, [\'Member\'], [])\n+ self.portal.acl_users._doAddUser(user2, TEST_USER_PASSWORD, ["Member"], [])\n \n def nofx(self):\n # Removes effective and expires to make sure we only test\n # the DateRangeIndex.\n- self.catalog.delIndex(\'effective\')\n- self.catalog.delIndex(\'expires\')\n+ self.catalog.delIndex("effective")\n+ self.catalog.delIndex("expires")\n \n def assertResults(self, result, expect):\n # Verifies ids of catalog results against expected ids\n@@ -1118,54 +1163,53 @@ def testPathWithPrivateMidLevel(self):\n self.logout()\n \n # Check that search shows both self.folder and self.folder.doc\n- path = \'/\'.join(self.folder.aq_parent.getPhysicalPath())\n+ path = "/".join(self.folder.aq_parent.getPhysicalPath())\n results = [b.getPath() for b in self.catalog(path=path)]\n- self.assertIn(\'/\'.join(self.folder.getPhysicalPath()), results)\n- self.assertIn(\'/\'.join(self.folder.doc.getPhysicalPath()), results)\n+ self.assertIn("/".join(self.folder.getPhysicalPath()), results)\n+ self.assertIn("/".join(self.folder.doc.getPhysicalPath()), results)\n \n # Hide self.folder from anonymous, but leave self.folder.doc visible\n self.login(TEST_USER_NAME)\n- self.portal.portal_workflow.doActionFor(self.folder, \'hide\')\n+ self.portal.portal_workflow.doActionFor(self.folder, "hide")\n self.logout()\n \n # Check that self.folder.doc is still visible while self.folder is not\n results = [b.getPath() for b in self.catalog(path=path)]\n- self.assertNotIn(\'/\'.join(self.folder.getPhysicalPath()), results)\n- self.assertIn(\'/\'.join(self.folder.doc.getPhysicalPath()), results)\n+ self.assertNotIn("/".join(self.folder.getPhysicalPath()), results)\n+ self.assertIn("/".join(self.folder.doc.getPhysicalPath()), results)\n \n # Check that direct search for self.folder.doc can be made\n- path = \'/\'.join(self.folder.doc.getPhysicalPath())\n+ path = "/".join(self.folder.doc.getPhysicalPath())\n results = [b.getPath() for b in self.catalog(path=path)]\n- self.assertIn(\'/\'.join(self.folder.doc.getPhysicalPath()), results)\n+ self.assertIn("/".join(self.folder.doc.getPhysicalPath()), results)\n \n def testUnauthorizedIsNotRaisedOnShowInactive(self):\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n wf_tool = self.portal.portal_workflow\n- self.portal.invokeFactory(\'Folder\', id=\'folder1\')\n- folder = self.portal[\'folder1\']\n- wf_tool.doActionFor(folder, \'publish\', comment=\'\')\n+ self.portal.invokeFactory("Folder", id="folder1")\n+ folder = self.portal["folder1"]\n+ wf_tool.doActionFor(folder, "publish", comment="")\n folder.reindexObject()\n \n- folder.invokeFactory(\'Folder\', id=\'folder2\')\n- folder2 = folder[\'folder2\']\n- wf_tool.doActionFor(folder2, \'hide\', comment=\'\')\n+ folder.invokeFactory("Folder", id="folder2")\n+ folder2 = folder["folder2"]\n+ wf_tool.doActionFor(folder2, "hide", comment="")\n folder2.reindexObject()\n \n- folder2.invokeFactory(\'Document\', id=\'doc1\')\n- doc = folder2[\'doc1\']\n- wf_tool.doActionFor(doc, \'publish\', comment=\'\')\n+ folder2.invokeFactory("Document", id="doc1")\n+ doc = folder2["doc1"]\n+ wf_tool.doActionFor(doc, "publish", comment="")\n doc.reindexObject()\n \n- folder2.invokeFactory(\'Document\', id=\'doc2\')\n- doc2 = folder2[\'doc2\']\n- wf_tool.doActionFor(doc2, \'hide\', comment=\'\')\n+ folder2.invokeFactory("Document", id="doc2")\n+ doc2 = folder2["doc2"]\n+ wf_tool.doActionFor(doc2, "hide", comment="")\n doc2.reindexObject()\n \n self.logout()\n- path = \'/\' + folder2.absolute_url(1)\n+ path = "/" + folder2.absolute_url(1)\n results = self.catalog.searchResults(path=path)\n- self.assertEqual(\n- results[0].getPath(), \'/plone/folder1/folder2/doc1\')\n+ self.assertEqual(results[0].getPath(), "/plone/folder1/folder2/doc1")\n self.assertEqual(len(results), 1)\n \n def testExpiredWithPermissionOnSubpath(self):\n@@ -1176,33 +1220,27 @@ def testExpiredWithPermissionOnSubpath(self):\n # Login as unprivileged user\n self.login(user2)\n \n- self.folder.manage_role(\'Member\', [AccessInactivePortalContent])\n+ self.folder.manage_role("Member", [AccessInactivePortalContent])\n \n- expected_result = [\'doc\', \'test_user_1_\']\n+ expected_result = ["doc", "test_user_1_"]\n \n- query = {\n- \'path\': \'/\'.join(self.folder.getPhysicalPath())\n- }\n+ query = {"path": "/".join(self.folder.getPhysicalPath())}\n res = self.catalog.searchResults(**query)\n self.assertResults(res, expected_result)\n res = self.catalog(**query)\n self.assertResults(res, expected_result)\n \n- query = {\n- \'path\': {\n- \'query\': \'/\'.join(self.folder.getPhysicalPath())\n- }\n- }\n+ query = {"path": {"query": "/".join(self.folder.getPhysicalPath())}}\n res = self.catalog.searchResults(**query)\n self.assertResults(res, expected_result)\n res = self.catalog(**query)\n self.assertResults(res, expected_result)\n \n query = {\n- \'path\': {\n- \'query\': [\n- \'/\'.join(self.folder.getPhysicalPath()),\n- \'/\'.join(self.folder.doc.getPhysicalPath()),\n+ "path": {\n+ "query": [\n+ "/".join(self.folder.getPhysicalPath()),\n+ "/".join(self.folder.doc.getPhysicalPath()),\n ]\n }\n }\n@@ -1220,31 +1258,25 @@ def testExpiredWithoutPermissionOnSubpath(self):\n self.login(user2)\n \n # Inactive content isn\'t shown without the required permission.\n- expected_result = [\'test_user_1_\']\n+ expected_result = ["test_user_1_"]\n \n- query = {\n- \'path\': \'/\'.join(self.folder.getPhysicalPath())\n- }\n+ query = {"path": "/".join(self.folder.getPhysicalPath())}\n res = self.catalog.searchResults(**query)\n self.assertResults(res, expected_result)\n res = self.catalog(**query)\n self.assertResults(res, expected_result)\n \n- query = {\n- \'path\': {\n- \'query\': \'/\'.join(self.folder.getPhysicalPath())\n- }\n- }\n+ query = {"path": {"query": "/".join(self.folder.getPhysicalPath())}}\n res = self.catalog.searchResults(**query)\n self.assertResults(res, expected_result)\n res = self.catalog(**query)\n self.assertResults(res, expected_result)\n \n query = {\n- \'path\': {\n- \'query\': [\n- \'/\'.join(self.folder.getPhysicalPath()),\n- \'/\'.join(self.folder.doc.getPhysicalPath()),\n+ "path": {\n+ "query": [\n+ "/".join(self.folder.getPhysicalPath()),\n+ "/".join(self.folder.doc.getPhysicalPath()),\n ]\n }\n }\n@@ -1255,12 +1287,12 @@ def testExpiredWithoutPermissionOnSubpath(self):\n \n def testExpiredWithSameNameAsSite(self):\n # Create an expired folder with the same name as the site\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n- self.portal.invokeFactory(\'Folder\', id=self.portal.id)\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n+ self.portal.invokeFactory("Folder", id=self.portal.id)\n \n # Add the AccessInactivePortalContent permission in the plone folder\n # The user should NOT have this permission in self.folder\n- self.portal.plone.manage_role(\'Member\', [AccessInactivePortalContent])\n+ self.portal.plone.manage_role("Member", [AccessInactivePortalContent])\n \n # Expire a document\n self.folder.doc.setExpirationDate(DateTime(2000, 12, 31))\n@@ -1268,15 +1300,15 @@ def testExpiredWithSameNameAsSite(self):\n self.nofx()\n \n # Inactive content isn\'t shown without the required permission.\n- expected_result = [content for content in base_content if content != \'doc\'] + [\'plone\']\n+ expected_result = [content for content in base_content if content != "doc"] + [\n+ "plone"\n+ ]\n \n # Login as unprivileged user\n self.login(user2)\n \n # Path is the site\'s one\n- query = {\n- \'path\': \'/\'.join(self.portal.getPhysicalPath())\n- }\n+ query = {"path": "/".join(self.portal.getPhysicalPath())}\n res = self.catalog.searchResults(**query)\n self.assertResults(res, expected_result)\n res = self.catalog(**query)\n@@ -1296,9 +1328,11 @@ def testSearchResultsWithAdditionalExpiryFilter(self):\n self.assertResults(res, base_content)\n # We should be able to further limit the search using the exipres\n # and efective indices.\n- res = self.catalog.searchResults({\n- \'expires\': {\'query\': DateTime() + 3, \'range\': \'min\'},\n- })\n+ res = self.catalog.searchResults(\n+ {\n+ "expires": {"query": DateTime() + 3, "range": "min"},\n+ }\n+ )\n \n self.assertResults(res, base_content[:-1])\n \n@@ -1309,39 +1343,40 @@ def testSearchResultsExpiredWithAdditionalExpiryFilter(self):\n res = self.catalog.searchResults()\n self.assertResults(res, base_content[:-1])\n # Even if we explicitly ask for it, we shouldn\'t get expired content\n- res = self.catalog.searchResults({\n- \'expires\': {\'query\': DateTime() - 3, \'range\': \'min\'},\n- })\n+ res = self.catalog.searchResults(\n+ {\n+ "expires": {"query": DateTime() - 3, "range": "min"},\n+ }\n+ )\n self.assertResults(res, base_content[:-1])\n \n \n def dummyMethod(obj, **kwargs):\n- return \'a dummy\'\n+ return "a dummy"\n \n \n class TestIndexers(PloneTestCase):\n- """Tests for IIndexer adapters\n- """\n+ """Tests for IIndexer adapters"""\n \n def afterSetUp(self):\n- self.folder.invokeFactory(\'Document\', \'doc\', title=\'document\')\n+ self.folder.invokeFactory("Document", "doc", title="document")\n self.doc = self.folder.doc\n \n def testSetup(self):\n doc = self.doc\n- self.assertEqual(doc.getId(), \'doc\')\n- self.assertEqual(doc.Title(), \'document\')\n+ self.assertEqual(doc.getId(), "doc")\n+ self.assertEqual(doc.Title(), "document")\n \n def test_is_folderishWithNonFolder(self):\n i = dummy.Item()\n self.assertFalse(is_folderish(i)())\n \n def test_is_folderishWithFolder(self):\n- f = dummy.Folder(\'struct_folder\')\n+ f = dummy.Folder("struct_folder")\n self.assertTrue(is_folderish(f)())\n \n def test_is_folderishWithNonStructuralFolder(self):\n- f = dummy.NonStructuralFolder(\'ns_folder\')\n+ f = dummy.NonStructuralFolder("ns_folder")\n self.assertFalse(is_folderish(f)())\n \n def test_provided(self):\n@@ -1357,17 +1392,19 @@ def test_provided(self):\n \n def test_getObjSize_KB(self):\n from Products.CMFPlone.CatalogTool import getObjSize\n+\n get_size = getObjSize.callable\n- self.doc.text = RichTextValue(\'a\' * 1000)\n+ self.doc.text = RichTextValue("a" * 1000)\n self.doc.reindexObject()\n- self.assertEqual(get_size(self.doc), \'1 KB\')\n+ self.assertEqual(get_size(self.doc), "1 KB")\n \n def test_getObjSize_MB(self):\n from Products.CMFPlone.CatalogTool import getObjSize\n+\n get_size = getObjSize.callable\n- self.doc.text = RichTextValue(\'a\' * 6000000)\n+ self.doc.text = RichTextValue("a" * 6000000)\n self.doc.reindexObject()\n- self.assertEqual(get_size(self.doc), \'5.7 MB\')\n+ self.assertEqual(get_size(self.doc), "5.7 MB")\n \n def test_uuid(self):\n alsoProvides(self.doc, IAttributeUUID)\n@@ -1380,14 +1417,15 @@ def test_uuid(self):\n \n \n class TestObjectProvidedIndexExtender(unittest.TestCase):\n-\n def _index(self, object):\n from Products.CMFPlone.CatalogTool import object_provides\n+\n return object_provides(object)()\n \n def testNoInterfaces(self):\n class Dummy:\n pass\n+\n self.assertEqual(self._index(Dummy()), ())\n \n def testSimpleInterface(self):\n@@ -1397,7 +1435,7 @@ class IDummy(zope.interface.Interface):\n @zope.interface.implementer(IDummy)\n class Dummy:\n pass\n+\n self.assertEqual(\n- self._index(Dummy()),\n- (\'Products.CMFPlone.tests.testCatalogTool.IDummy\', )\n+ self._index(Dummy()), ("Products.CMFPlone.tests.testCatalogTool.IDummy",)\n )\ndiff --git a/Products/CMFPlone/tests/testCheckId.py b/Products/CMFPlone/tests/testCheckId.py\nindex 89017a733b..df213e1ff4 100644\n--- a/Products/CMFPlone/tests/testCheckId.py\n+++ b/Products/CMFPlone/tests/testCheckId.py\n@@ -7,131 +7,129 @@\n \n \n class TestCheckId(PloneTestCase):\n-\n def testGoodId(self):\n- r = check_id(self.folder, \'foo\')\n- self.assertEqual(r, None) # success\n+ r = check_id(self.folder, "foo")\n+ self.assertEqual(r, None) # success\n \n def testEmptyId(self):\n- r = check_id(self.folder, \'\')\n- self.assertEqual(r, None) # success\n+ r = check_id(self.folder, "")\n+ self.assertEqual(r, None) # success\n \n def testRequiredId(self):\n- r = check_id(self.folder, \'\', required=1)\n- self.assertEqual(r, \'Please enter a name.\')\n+ r = check_id(self.folder, "", required=1)\n+ self.assertEqual(r, "Please enter a name.")\n \n def testAlternativeId(self):\n- r = check_id(self.folder, \'\', alternative_id=\'foo\')\n- self.assertEqual(r, None) # success\n+ r = check_id(self.folder, "", alternative_id="foo")\n+ self.assertEqual(r, None) # success\n \n def testBadId(self):\n # See https://github.com/zopefoundation/Zope/pull/181\n- r = check_id(self.folder, \'=\')\n+ r = check_id(self.folder, "=")\n self.assertEqual(r, None)\n \n def testDecodeId(self):\n # See https://github.com/zopefoundation/Zope/pull/181\n- r = check_id(self.folder, \'\\xc3\\xa4\')\n+ r = check_id(self.folder, "\\xc3\\xa4")\n self.assertEqual(r, None)\n \n def testCatalogIndex(self):\n # TODO: Tripwire\n- portal_membership = getToolByName(self.portal, \'portal_membership\')\n+ portal_membership = getToolByName(self.portal, "portal_membership")\n have_permission = portal_membership.checkPermission\n- self.assertTrue(have_permission(\'Search ZCatalog\',\n- self.portal.portal_catalog),\n- \'Expected permission "Search ZCatalog"\')\n+ self.assertTrue(\n+ have_permission("Search ZCatalog", self.portal.portal_catalog),\n+ \'Expected permission "Search ZCatalog"\',\n+ )\n \n- r = check_id(self.folder, \'created\')\n- self.assertEqual(r, \'created is reserved.\')\n+ r = check_id(self.folder, "created")\n+ self.assertEqual(r, "created is reserved.")\n \n def testCatalogMetadata(self):\n- portal_catalog = getToolByName(self.portal, \'portal_catalog\')\n- portal_catalog.addColumn(\'new_metadata\')\n- self.assertTrue(\'new_metadata\' in portal_catalog.schema())\n- self.assertFalse(\'new_metadata\' in portal_catalog.indexes())\n- r = check_id(self.folder, \'new_metadata\')\n- self.assertEqual(r, \'new_metadata is reserved.\')\n+ portal_catalog = getToolByName(self.portal, "portal_catalog")\n+ portal_catalog.addColumn("new_metadata")\n+ self.assertTrue("new_metadata" in portal_catalog.schema())\n+ self.assertFalse("new_metadata" in portal_catalog.indexes())\n+ r = check_id(self.folder, "new_metadata")\n+ self.assertEqual(r, "new_metadata is reserved.")\n \n def testCollision(self):\n- self.folder.invokeFactory(\'Document\', id=\'foo\')\n- self.folder.invokeFactory(\'Document\', id=\'bar\')\n- r = check_id(self.folder.foo, \'bar\')\n- self.assertEqual(r, \'There is already an item named bar in this \'\n- \'folder.\')\n+ self.folder.invokeFactory("Document", id="foo")\n+ self.folder.invokeFactory("Document", id="bar")\n+ r = check_id(self.folder.foo, "bar")\n+ self.assertEqual(r, "There is already an item named bar in this " "folder.")\n \n def testReservedId(self):\n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n- r = check_id(self.folder.foo, \'portal_catalog\')\n- self.assertEqual(r, \'portal_catalog is reserved.\')\n+ self.folder._setObject("foo", dummy.Item("foo"))\n+ r = check_id(self.folder.foo, "portal_catalog")\n+ self.assertEqual(r, "portal_catalog is reserved.")\n \n def testHiddenObjectId(self):\n # If a parallel object is not in content-space, should get \'reserved\'\n # instead of \'taken\'\n- r = check_id(self.folder, \'portal_skins\')\n- self.assertEqual(r, \'portal_skins is reserved.\')\n+ r = check_id(self.folder, "portal_skins")\n+ self.assertEqual(r, "portal_skins is reserved.")\n \n def testCanOverrideParentNames(self):\n- self.folder.invokeFactory(\'Document\', id=\'item1\')\n- self.folder.invokeFactory(\'Folder\', id=\'folder1\')\n- self.folder.invokeFactory(\'Document\', id=\'foo\')\n- r = check_id(self.folder.folder1.foo, \'item1\')\n+ self.folder.invokeFactory("Document", id="item1")\n+ self.folder.invokeFactory("Folder", id="folder1")\n+ self.folder.invokeFactory("Document", id="foo")\n+ r = check_id(self.folder.folder1.foo, "item1")\n self.assertEqual(r, None)\n \n def testInvalidId(self):\n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n- r = check_id(self.folder.foo, \'_foo\')\n- self.assertEqual(r, \'_foo is reserved.\')\n+ self.folder._setObject("foo", dummy.Item("foo"))\n+ r = check_id(self.folder.foo, "_foo")\n+ self.assertEqual(r, "_foo is reserved.")\n \n def testContainerHook(self):\n # Container may have a checkValidId method; make sure it is called\n- self.folder._setObject(\'checkValidId\', dummy.Raiser(dummy.Error))\n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n- r = check_id(self.folder.foo, \'whatever\')\n- self.assertEqual(r, \'whatever is reserved.\')\n+ self.folder._setObject("checkValidId", dummy.Raiser(dummy.Error))\n+ self.folder._setObject("foo", dummy.Item("foo"))\n+ r = check_id(self.folder.foo, "whatever")\n+ self.assertEqual(r, "whatever is reserved.")\n \n def testContainerHookRaisesUnauthorized(self):\n # check_id does not raise Unauthorized errors raised by hook\n- self.folder._setObject(\'checkValidId\', dummy.Raiser(Unauthorized))\n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n- r = check_id(self.folder.foo, \'whatever\')\n- self.assertEqual(r, \'whatever is reserved.\')\n+ self.folder._setObject("checkValidId", dummy.Raiser(Unauthorized))\n+ self.folder._setObject("foo", dummy.Item("foo"))\n+ r = check_id(self.folder.foo, "whatever")\n+ self.assertEqual(r, "whatever is reserved.")\n \n def testContainerHookRaisesConflictError(self):\n # check_id should not swallow ConflictErrors raised by hook\n- self.folder._setObject(\'checkValidId\', dummy.Raiser(ConflictError))\n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n+ self.folder._setObject("checkValidId", dummy.Raiser(ConflictError))\n+ self.folder._setObject("foo", dummy.Item("foo"))\n with self.assertRaises(ConflictError):\n- check_id(self.folder.foo, \'whatever\')\n+ check_id(self.folder.foo, "whatever")\n \n def testMissingUtils(self):\n # check_id should not bomb out if the plone_utils tool is missing\n- self.portal._delObject(\'plone_utils\')\n- r = check_id(self.folder, \'foo\')\n- self.assertEqual(r, None) # success\n+ self.portal._delObject("plone_utils")\n+ r = check_id(self.folder, "foo")\n+ self.assertEqual(r, None) # success\n \n def testMissingCatalog(self):\n # check_id should not bomb out if the portal_catalog tool is missing\n- self.portal._delObject(\'portal_catalog\')\n- r = check_id(self.folder, \'foo\')\n- self.assertEqual(r, None) # success\n+ self.portal._delObject("portal_catalog")\n+ r = check_id(self.folder, "foo")\n+ self.assertEqual(r, None) # success\n \n def testMissingFactory(self):\n # check_id should not bomb out if the portal_factory tool is missing\n- if \'portal_factory\' in self.portal:\n- self.portal._delObject(\'portal_factory\')\n- r = check_id(self.folder, \'foo\')\n- self.assertEqual(r, None) # success\n+ if "portal_factory" in self.portal:\n+ self.portal._delObject("portal_factory")\n+ r = check_id(self.folder, "foo")\n+ self.assertEqual(r, None) # success\n \n def testCatalogIndexSkipped(self):\n # Note that the check is skipped when we don\'t have\n # the "Search ZCatalogs" permission.\n- self.portal.manage_permission(\'Search ZCatalog\', [\'Manager\'],\n- acquire=0)\n+ self.portal.manage_permission("Search ZCatalog", ["Manager"], acquire=0)\n \n- r = check_id(self.folder, \'created\')\n+ r = check_id(self.folder, "created")\n # But now the final hasattr check picks this up\n- self.assertEqual(r, \'created is reserved.\')\n+ self.assertEqual(r, "created is reserved.")\n \n def testCollisionNotSkipped(self):\n # Note that the existing object check is done, even when we don\'t have\n@@ -141,53 +139,50 @@ def testCollisionNotSkipped(self):\n # because check_id was a skin script. Since Plone 5.2 it is a\n # function which cannot be accessed from the web or templates,\n # so the permission test seems unneeded.\n- self.folder.manage_permission(\'Access contents information\', [],\n- acquire=0)\n+ self.folder.manage_permission("Access contents information", [], acquire=0)\n \n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n- self.folder._setObject(\'bar\', dummy.Item(\'bar\'))\n- r = check_id(self.folder.foo, \'bar\')\n- self.assertEqual(r, \'bar is reserved.\')\n+ self.folder._setObject("foo", dummy.Item("foo"))\n+ self.folder._setObject("bar", dummy.Item("bar"))\n+ r = check_id(self.folder.foo, "bar")\n+ self.assertEqual(r, "bar is reserved.")\n \n def testReservedIdSkipped(self):\n # This check is picked up by the checkIdAvailable, unless we don\'t have\n # the "Add portal content" permission, in which case it is picked up by\n # the final hasattr check.\n- self.folder.manage_permission(\'Add portal content\', [], acquire=0)\n+ self.folder.manage_permission("Add portal content", [], acquire=0)\n \n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n- r = check_id(self.folder.foo, \'portal_catalog\')\n- self.assertEqual(r, \'portal_catalog is reserved.\')\n+ self.folder._setObject("foo", dummy.Item("foo"))\n+ r = check_id(self.folder.foo, "portal_catalog")\n+ self.assertEqual(r, "portal_catalog is reserved.")\n \n def testInvalidIdSkipped(self):\n # Note that the check is skipped when we don\'t have\n # the "Add portal content" permission.\n- self.folder.manage_permission(\'Add portal content\', [], acquire=0)\n+ self.folder.manage_permission("Add portal content", [], acquire=0)\n \n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n- r = check_id(self.folder.foo, \'_foo\')\n- self.assertEqual(r, None) # success\n+ self.folder._setObject("foo", dummy.Item("foo"))\n+ r = check_id(self.folder.foo, "_foo")\n+ self.assertEqual(r, None) # success\n \n def testParentMethodAliasDisallowed(self):\n # Note that the check is skipped when we don\'t have\n # the "Add portal content" permission.\n- self.folder.manage_permission(\'Add portal content\', [\'Manager\'],\n- acquire=0)\n+ self.folder.manage_permission("Add portal content", ["Manager"], acquire=0)\n \n- self.folder._setObject(\'foo\', dummy.Item(\'foo\'))\n+ self.folder._setObject("foo", dummy.Item("foo"))\n for alias in self.folder.getTypeInfo().getMethodAliases().keys():\n r = check_id(self.folder.foo, alias)\n- self.assertEqual(r, \'%s is reserved.\' % alias)\n+ self.assertEqual(r, "%s is reserved." % alias)\n \n def testCheckingMethodAliasesOnPortalRoot(self):\n # Test for bug http://dev.plone.org/plone/ticket/4351\n- self.setRoles([\'Manager\'])\n- self.portal.manage_permission(\'Add portal content\', [\'Manager\'],\n- acquire=0)\n+ self.setRoles(["Manager"])\n+ self.portal.manage_permission("Add portal content", ["Manager"], acquire=0)\n \n # Should not raise: Before we were using obj.getTypeInfo(), which is\n # not defined on the portal root.\n try:\n- check_id(self.portal, \'foo\')\n+ check_id(self.portal, "foo")\n except AttributeError as e:\n self.fail(e)\ndiff --git a/Products/CMFPlone/tests/testContentSecurity.py b/Products/CMFPlone/tests/testContentSecurity.py\nindex aea5cc0e2a..aa9df204c2 100644\n--- a/Products/CMFPlone/tests/testContentSecurity.py\n+++ b/Products/CMFPlone/tests/testContentSecurity.py\n@@ -7,17 +7,16 @@\n \n \n class TestContentSecurity(PloneTestCase):\n-\n def afterSetUp(self):\n self.request = self.layer["request"]\n- self.portal.acl_users._doAddUser(\'user1\', TEST_USER_PASSWORD, [\'Member\'], [])\n- self.portal.acl_users._doAddUser(\'user2\', TEST_USER_PASSWORD, [\'Member\'], [])\n- #_ender_\'s member who\'s not a Member usecase\n- self.portal.acl_users._doAddUser(\'user3\', TEST_USER_PASSWORD, [], [])\n+ self.portal.acl_users._doAddUser("user1", TEST_USER_PASSWORD, ["Member"], [])\n+ self.portal.acl_users._doAddUser("user2", TEST_USER_PASSWORD, ["Member"], [])\n+ # _ender_\'s member who\'s not a Member usecase\n+ self.portal.acl_users._doAddUser("user3", TEST_USER_PASSWORD, [], [])\n self.membership = self.portal.portal_membership\n self.workflow = self.portal.portal_workflow\n- self.createMemberarea(\'user1\')\n- self.createMemberarea(\'user2\')\n+ self.createMemberarea("user1")\n+ self.createMemberarea("user2")\n \n def setup_authenticator(self):\n from plone.protect.authenticator import createToken\n@@ -30,116 +29,115 @@ def get_content_status_modify_view(self, obj):\n return view\n \n def testCreateMemberContent(self):\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user1\')\n- folder.invokeFactory(\'Document\', id=\'new\')\n- self.assertTrue(hasattr(aq_base(folder), \'new\'))\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user1")\n+ folder.invokeFactory("Document", id="new")\n+ self.assertTrue(hasattr(aq_base(folder), "new"))\n \n def testCreateOtherMemberContentFails(self):\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user2\')\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user2")\n with self.assertRaises(zUnauthorized):\n- folder.invokeFactory(\'Document\', \'new\')\n+ folder.invokeFactory("Document", "new")\n \n def testCreateRootContentFails(self):\n- self.login(\'user1\')\n+ self.login("user1")\n with self.assertRaises(Unauthorized):\n- self.portal.invokeFactory(\'Document\', \'new\')\n+ self.portal.invokeFactory("Document", "new")\n \n def testDeleteMemberContent(self):\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user1\')\n- folder.invokeFactory(\'Document\', id=\'new\')\n- folder.manage_delObjects([\'new\'])\n- self.assertFalse(hasattr(aq_base(folder), \'new\'))\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user1")\n+ folder.invokeFactory("Document", id="new")\n+ folder.manage_delObjects(["new"])\n+ self.assertFalse(hasattr(aq_base(folder), "new"))\n \n def testDeleteOtherMemberContent(self):\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user1\')\n- folder.invokeFactory(\'Document\', id=\'new\')\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user1")\n+ folder.invokeFactory("Document", id="new")\n \n- self.login(\'user2\')\n- folder = self.membership.getHomeFolder(\'user1\')\n+ self.login("user2")\n+ folder = self.membership.getHomeFolder("user1")\n with self.assertRaises(zUnauthorized):\n- folder.manage_delObjects([\'new\'])\n+ folder.manage_delObjects(["new"])\n \n def testCreateWithLocalRole(self):\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user1\')\n- folder.manage_addLocalRoles(\'user2\', (\'Owner\',))\n- self.login(\'user2\')\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user1")\n+ folder.manage_addLocalRoles("user2", ("Owner",))\n+ self.login("user2")\n # This will raise Unauthorized if the role is not set\n- folder.invokeFactory(\'Document\', id=\'new\')\n+ folder.invokeFactory("Document", id="new")\n \n def testCreateFailsWithLocalRoleBlocked(self):\n # Ensure that local role blocking works for blocking content creation\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user1\')\n- folder.manage_addLocalRoles(\'user2\', (\'Owner\',))\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user1")\n+ folder.manage_addLocalRoles("user2", ("Owner",))\n \n- sharingView = self.folder.unrestrictedTraverse(\'@@sharing\')\n- sharingView.update_role_settings([{\'id\': \'user2\',\n- \'type\': \'user\',\n- \'roles\': [\'Owner\']}])\n+ sharingView = self.folder.unrestrictedTraverse("@@sharing")\n+ sharingView.update_role_settings(\n+ [{"id": "user2", "type": "user", "roles": ["Owner"]}]\n+ )\n \n- folder.invokeFactory(\'Folder\', id=\'subfolder\')\n+ folder.invokeFactory("Folder", id="subfolder")\n # Turn off local role acquisition\n- folder.subfolder.unrestrictedTraverse(\'@@sharing\') \\\n- .update_inherit(False)\n+ folder.subfolder.unrestrictedTraverse("@@sharing").update_inherit(False)\n \n- self.login(\'user2\')\n+ self.login("user2")\n # This should now raise ValueError\n with self.assertRaises(zUnauthorized):\n- folder.subfolder.invokeFactory(\'Document\', \'new\')\n+ folder.subfolder.invokeFactory("Document", "new")\n \n def testCreateSucceedsWithLocalRoleBlockedInParentButAssingedInSubFolder(self):\n # Make sure that blocking a acquisition in a folder does not interfere\n # with assigning a role in subfolders\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user1\')\n- folder.manage_addLocalRoles(\'user2\', (\'Owner\',))\n- folder.invokeFactory(\'Folder\', id=\'subfolder\')\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user1")\n+ folder.manage_addLocalRoles("user2", ("Owner",))\n+ folder.invokeFactory("Folder", id="subfolder")\n subfolder = folder.subfolder\n # Turn off local role acquisition\n- subfolder.unrestrictedTraverse(\'@@sharing\').update_inherit(False)\n- subfolder.invokeFactory(\'Folder\', id=\'subsubfolder\')\n- subfolder.subsubfolder.manage_addLocalRoles(\'user2\', (\'Owner\',))\n- self.login(\'user2\')\n+ subfolder.unrestrictedTraverse("@@sharing").update_inherit(False)\n+ subfolder.invokeFactory("Folder", id="subsubfolder")\n+ subfolder.subsubfolder.manage_addLocalRoles("user2", ("Owner",))\n+ self.login("user2")\n # This should not raise Unauthorized\n- subfolder.subsubfolder.invokeFactory(\'Document\', id=\'new\')\n+ subfolder.subsubfolder.invokeFactory("Document", id="new")\n \n def testViewAllowedOnContentInAcquisitionBlockedFolder(self):\n # Test for http://dev.plone.org/plone/ticket/4055 which seems to be\n # invalid\n- self.login(\'user1\')\n+ self.login("user1")\n self.setupAuthenticator()\n- folder = self.membership.getHomeFolder(\'user1\')\n- self.setRequestMethod(\'POST\')\n- folder.manage_addLocalRoles(\'user2\', (\'Owner\',))\n- self.setRequestMethod(\'GET\')\n- folder.invokeFactory(\'Folder\', id=\'subfolder\')\n+ folder = self.membership.getHomeFolder("user1")\n+ self.setRequestMethod("POST")\n+ folder.manage_addLocalRoles("user2", ("Owner",))\n+ self.setRequestMethod("GET")\n+ folder.invokeFactory("Folder", id="subfolder")\n subfolder = folder.subfolder\n- subfolder.unrestrictedTraverse(\'@@sharing\').update_inherit(False)\n+ subfolder.unrestrictedTraverse("@@sharing").update_inherit(False)\n # Turn off local role acquisition\n- subfolder.invokeFactory(\'Document\', id=\'new\')\n+ subfolder.invokeFactory("Document", id="new")\n view = self.get_content_status_modify_view(subfolder.new)\n- view(workflow_action=\'publish\')\n- subfolder.new.manage_addLocalRoles(\'user2\', (\'Member\',))\n- self.login(\'user2\')\n+ view(workflow_action="publish")\n+ subfolder.new.manage_addLocalRoles("user2", ("Member",))\n+ self.login("user2")\n # This should not raise Unauthorized\n subfolder.new.view()\n \n def testViewAllowedOnContentInPrivateFolder(self):\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user1\')\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user1")\n view = self.get_content_status_modify_view(folder)\n- view(workflow_action=\'private\')\n- folder.invokeFactory(\'Document\', id=\'doc1\')\n+ view(workflow_action="private")\n+ folder.invokeFactory("Document", id="doc1")\n doc = folder.doc1\n view = self.get_content_status_modify_view(doc)\n- view(workflow_action=\'publish\')\n- doc.manage_addLocalRoles(\'user2\', (\'Owner\',))\n- self.login(\'user2\')\n+ view(workflow_action="publish")\n+ doc.manage_addLocalRoles("user2", ("Owner",))\n+ self.login("user2")\n # This should not raise Unauthorized\n doc.view()\n # Neither should anonymous\n@@ -155,32 +153,34 @@ def testViewAllowedOnContentInAcquisitionBlockedFolderWithCustomWorkflow(self):\n # Create more private workflow starting with folder_workflow\n wf = self.portal.portal_workflow.folder_workflow\n visible = wf.states.visible\n- visible.setPermission(\'View\', 0, (\'Manager\', \'Owner\'))\n- visible.setPermission(\'Modify portal content\', 0, (\'Manager\', \'Owner\'))\n+ visible.setPermission("View", 0, ("Manager", "Owner"))\n+ visible.setPermission("Modify portal content", 0, ("Manager", "Owner"))\n # Then plone workflow\n p_wf = self.portal.portal_workflow.plone_workflow\n published = p_wf.states.published\n- published.setPermission(\'View\', 0, (\'Manager\', \'Member\', \'Owner\'))\n- published.setPermission(\'Access contents information\', 0,\n- (\'Manager\', \'Member\', \'Owner\'))\n- published.setPermission(\'Modify portal content\', 0,\n- (\'Manager\', \'Member\', \'Owner\'))\n+ published.setPermission("View", 0, ("Manager", "Member", "Owner"))\n+ published.setPermission(\n+ "Access contents information", 0, ("Manager", "Member", "Owner")\n+ )\n+ published.setPermission(\n+ "Modify portal content", 0, ("Manager", "Member", "Owner")\n+ )\n self.portal.portal_workflow.updateRoleMappings()\n \n- self.login(\'user1\')\n+ self.login("user1")\n self.setupAuthenticator()\n- self.setRequestMethod(\'POST\')\n- folder = self.membership.getHomeFolder(\'user1\')\n- self.setRequestMethod(\'GET\')\n- folder.manage_addLocalRoles(\'user2\', (\'Member\',))\n- folder.invokeFactory(\'Folder\', id=\'subfolder\')\n+ self.setRequestMethod("POST")\n+ folder = self.membership.getHomeFolder("user1")\n+ self.setRequestMethod("GET")\n+ folder.manage_addLocalRoles("user2", ("Member",))\n+ folder.invokeFactory("Folder", id="subfolder")\n subfolder = folder.subfolder\n- subfolder.unrestrictedTraverse(\'@@sharing\').update_inherit(False)\n- subfolder.invokeFactory(\'Document\', id=\'new\')\n+ subfolder.unrestrictedTraverse("@@sharing").update_inherit(False)\n+ subfolder.invokeFactory("Document", id="new")\n view = self.get_content_status_modify_view(subfolder.new)\n- view(workflow_action=\'publish\')\n- subfolder.new.manage_addLocalRoles(\'user3\', (\'Member\',))\n- self.login(\'user3\')\n+ view(workflow_action="publish")\n+ subfolder.new.manage_addLocalRoles("user3", ("Member",))\n+ self.login("user3")\n # This shouldn\'t either, but strangely it never does even if the script\n # below, which is called in here, does. What is wrong here?\n try:\ndiff --git a/Products/CMFPlone/tests/testControlPanel.py b/Products/CMFPlone/tests/testControlPanel.py\nindex 0ce80c7acf..e9720c25ba 100644\n--- a/Products/CMFPlone/tests/testControlPanel.py\n+++ b/Products/CMFPlone/tests/testControlPanel.py\n@@ -4,29 +4,40 @@\n \n \n class TestControlPanel(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.controlpanel = self.layer[\'portal\'].portal_controlpanel\n+ self.controlpanel = self.layer["portal"].portal_controlpanel\n \n # get the expected default groups and configlets\n- self.groups = [\'Plone\', \'Products\']\n- self.configlets = [\'QuickInstaller\', \'MailHost\',\n- \'UsersGroups\', \'PortalSkin\',\n- \'ZMI\', \'SecuritySettings\',\n- \'NavigationSettings\', \'SearchSettings\',\n- \'errorLog\', \'PloneReconfig\', \'TypesSettings\',\n- \'FilterSettings\',\n- \'Maintenance\']\n+ self.groups = ["Plone", "Products"]\n+ self.configlets = [\n+ "QuickInstaller",\n+ "MailHost",\n+ "UsersGroups",\n+ "PortalSkin",\n+ "ZMI",\n+ "SecuritySettings",\n+ "NavigationSettings",\n+ "SearchSettings",\n+ "errorLog",\n+ "PloneReconfig",\n+ "TypesSettings",\n+ "FilterSettings",\n+ "Maintenance",\n+ ]\n \n def testDefaultGroups(self):\n for group in self.groups:\n- self.assertTrue(group in self.controlpanel.getGroupIds(),\n- "Missing group with id \'%s\'" % group)\n+ self.assertTrue(\n+ group in self.controlpanel.getGroupIds(),\n+ "Missing group with id \'%s\'" % group,\n+ )\n \n def testDefaultConfiglets(self):\n for title in self.configlets:\n- self.assertTrue(title in [a.getAction(self)[\'id\']\n- for a in self.controlpanel.listActions()],\n- "Missing configlet with id \'%s\'" % title)\n+ self.assertTrue(\n+ title\n+ in [a.getAction(self)["id"] for a in self.controlpanel.listActions()],\n+ "Missing configlet with id \'%s\'" % title,\n+ )\ndiff --git a/Products/CMFPlone/tests/testControlPanelScripts.py b/Products/CMFPlone/tests/testControlPanelScripts.py\nindex d37e54f2ef..c82a3bfc7e 100644\n--- a/Products/CMFPlone/tests/testControlPanelScripts.py\n+++ b/Products/CMFPlone/tests/testControlPanelScripts.py\n@@ -5,24 +5,26 @@\n \n \n class TestAccessControlPanelScripts(PloneTestCase):\n- \'\'\'Yipee, functional tests\'\'\'\n+ """Yipee, functional tests"""\n \n def afterSetUp(self):\n self.portal_path = self.portal.absolute_url(1)\n- self.basic_auth = f\'{SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ self.basic_auth = f"{SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n \n def testUserInformation(self):\n- \'\'\'Test access to user details.\'\'\'\n- response = self.publish(\'%s/@@user-information?userid=%s\' %\n- (self.portal_path, TEST_USER_ID),\n- self.basic_auth)\n+ """Test access to user details."""\n+ response = self.publish(\n+ "%s/@@user-information?userid=%s" % (self.portal_path, TEST_USER_ID),\n+ self.basic_auth,\n+ )\n \n self.assertEqual(response.getStatus(), 200)\n \n def testUserPreferences(self):\n- \'\'\'Test access to user details.\'\'\'\n- response = self.publish(\'%s/@@user-preferences?userid=%s\' %\n- (self.portal_path, TEST_USER_ID),\n- self.basic_auth)\n+ """Test access to user details."""\n+ response = self.publish(\n+ "%s/@@user-preferences?userid=%s" % (self.portal_path, TEST_USER_ID),\n+ self.basic_auth,\n+ )\n \n self.assertEqual(response.getStatus(), 200)\ndiff --git a/Products/CMFPlone/tests/testCookieAuth.py b/Products/CMFPlone/tests/testCookieAuth.py\nindex 9c57d1fd2d..7fdb2e5638 100644\n--- a/Products/CMFPlone/tests/testCookieAuth.py\n+++ b/Products/CMFPlone/tests/testCookieAuth.py\n@@ -14,50 +14,47 @@\n \n \n class TestCookieAuth(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.folder = self.portal[\'test-folder\']\n- self.browser = Browser(self.layer[\'app\'])\n- self.auth_info = f\'{TEST_USER_NAME}:{TEST_USER_PASSWORD}\'\n- self.cookie = encodebytes(self.auth_info.encode(\'utf8\'))[:-1]\n- self.folder.manage_permission(\'View\', [\'Manager\'], acquire=0)\n+ self.portal = self.layer["portal"]\n+ self.folder = self.portal["test-folder"]\n+ self.browser = Browser(self.layer["app"])\n+ self.auth_info = f"{TEST_USER_NAME}:{TEST_USER_PASSWORD}"\n+ self.cookie = encodebytes(self.auth_info.encode("utf8"))[:-1]\n+ self.folder.manage_permission("View", ["Manager"], acquire=0)\n logout()\n \n def testAutoLoginPage(self):\n # Should send us to login_form\n self.browser.open(self.folder.absolute_url())\n- self.assertIn(\'200\', self.browser.headers[\'status\'])\n+ self.assertIn("200", self.browser.headers["status"])\n self.assertEqual(\n self.browser.url,\n- \'http://nohost/plone/login?came_from=/plone/test-folder\' # noqa: E501\n+ "http://nohost/plone/login?came_from=/plone/test-folder", # noqa: E501\n )\n \n def testInsufficientPrivileges(self):\n # Should send us to login_form\n self.browser.open(self.portal.absolute_url())\n- self.browser.cookies[\'__ac\'] = self.cookie\n+ self.browser.cookies["__ac"] = self.cookie\n self.browser.open(self.folder.absolute_url())\n- self.assertIn(\'200\', self.browser.headers[\'status\'])\n+ self.assertIn("200", self.browser.headers["status"])\n self.assertEqual(\n self.browser.url,\n- \'http://nohost/plone/login?came_from=/plone/test-folder\' # noqa: E501\n+ "http://nohost/plone/login?came_from=/plone/test-folder", # noqa: E501\n )\n \n def testSetSessionCookie(self):\n # The __ac cookie should be set for the session only\n- self.browser.open(\'http://nohost/plone/login\')\n- self.browser.getControl(name=\'__ac_name\').value = TEST_USER_NAME\n- self.browser.getControl(\n- name=\'__ac_password\'\n- ).value = TEST_USER_PASSWORD\n- self.browser.getControl(\'Log in\').click()\n- self.assertIn(\'200\', self.browser.headers[\'status\'])\n- self.assertIn(\'__ac\', self.browser.cookies)\n+ self.browser.open("http://nohost/plone/login")\n+ self.browser.getControl(name="__ac_name").value = TEST_USER_NAME\n+ self.browser.getControl(name="__ac_password").value = TEST_USER_PASSWORD\n+ self.browser.getControl("Log in").click()\n+ self.assertIn("200", self.browser.headers["status"])\n+ self.assertIn("__ac", self.browser.cookies)\n self.assertEqual(\n- self.browser.cookies.getinfo(\'__ac\')[\'path\'],\n- \'/\',\n+ self.browser.cookies.getinfo("__ac")["path"],\n+ "/",\n )\n- self.assertIsNone(self.browser.cookies.getinfo(\'__ac\')[\'expires\'])\n+ self.assertIsNone(self.browser.cookies.getinfo("__ac")["expires"])\ndiff --git a/Products/CMFPlone/tests/testCutPasteSecurity.py b/Products/CMFPlone/tests/testCutPasteSecurity.py\nindex bf99c6252e..a2d265f5c8 100644\n--- a/Products/CMFPlone/tests/testCutPasteSecurity.py\n+++ b/Products/CMFPlone/tests/testCutPasteSecurity.py\n@@ -13,99 +13,97 @@\n \n \n class TestCutPasteSecurity(PloneTestCase):\n-\n def afterSetUp(self):\n- self.portal.acl_users._doAddUser(\'user1\', TEST_USER_PASSWORD, [\'Member\'], [])\n- self.portal.acl_users._doAddUser(\'user2\', TEST_USER_PASSWORD, [\'Member\'], [])\n+ self.portal.acl_users._doAddUser("user1", TEST_USER_PASSWORD, ["Member"], [])\n+ self.portal.acl_users._doAddUser("user2", TEST_USER_PASSWORD, ["Member"], [])\n self.membership = self.portal.portal_membership\n- self.createMemberarea(\'user1\')\n- self.createMemberarea(\'user2\')\n+ self.createMemberarea("user1")\n+ self.createMemberarea("user2")\n \n def testRenameMemberContent(self):\n- self.login(\'user1\')\n- folder = self.membership.getHomeFolder(\'user1\')\n- folder.invokeFactory(\'Document\', id=\'testrename\')\n+ self.login("user1")\n+ folder = self.membership.getHomeFolder("user1")\n+ folder.invokeFactory("Document", id="testrename")\n \n # We need to commit here so that _p_jar isn\'t None and move\n # will work\n transaction.savepoint(optimistic=True)\n- folder.manage_renameObject(\'testrename\', \'new\')\n- self.assertFalse(hasattr(aq_base(folder), \'testrename\'))\n- self.assertTrue(hasattr(aq_base(folder), \'new\'))\n+ folder.manage_renameObject("testrename", "new")\n+ self.assertFalse(hasattr(aq_base(folder), "testrename"))\n+ self.assertTrue(hasattr(aq_base(folder), "new"))\n \n def testRenameOtherMemberContentFails(self):\n- self.login(\'user1\')\n- src = self.membership.getHomeFolder(\'user1\')\n- src.invokeFactory(\'Document\', id=\'testrename\')\n+ self.login("user1")\n+ src = self.membership.getHomeFolder("user1")\n+ src.invokeFactory("Document", id="testrename")\n \n- self.login(\'user2\')\n- folder = self.membership.getHomeFolder(\'user1\')\n+ self.login("user2")\n+ folder = self.membership.getHomeFolder("user1")\n with self.assertRaises(CopyError):\n- folder.manage_renameObject(\'testrename\', \'bad\')\n+ folder.manage_renameObject("testrename", "bad")\n \n def testCopyMemberContent(self):\n- self.login(\'user1\')\n- src = self.membership.getHomeFolder(\'user1\')\n- src.invokeFactory(\'Document\', id=\'testcopy\')\n- src.invokeFactory(\'Folder\', id=\'dest\')\n+ self.login("user1")\n+ src = self.membership.getHomeFolder("user1")\n+ src.invokeFactory("Document", id="testcopy")\n+ src.invokeFactory("Folder", id="dest")\n dest = src.dest\n- dest.manage_pasteObjects(src.manage_copyObjects(\'testcopy\'))\n+ dest.manage_pasteObjects(src.manage_copyObjects("testcopy"))\n \n # After a copy/paste, they should *both* have a copy\n- self.assertTrue(hasattr(aq_base(src), \'testcopy\'))\n- self.assertTrue(hasattr(aq_base(dest), \'testcopy\'))\n+ self.assertTrue(hasattr(aq_base(src), "testcopy"))\n+ self.assertTrue(hasattr(aq_base(dest), "testcopy"))\n \n def testCopyOtherMemberContent(self):\n- self.login(\'user1\')\n- src = self.membership.getHomeFolder(\'user1\')\n- src.invokeFactory(\'Document\', id=\'testcopy\')\n+ self.login("user1")\n+ src = self.membership.getHomeFolder("user1")\n+ src.invokeFactory("Document", id="testcopy")\n \n- self.login(\'user2\')\n- dest = self.membership.getHomeFolder(\'user2\')\n- dest.manage_pasteObjects(src.manage_copyObjects(\'testcopy\'))\n+ self.login("user2")\n+ dest = self.membership.getHomeFolder("user2")\n+ dest.manage_pasteObjects(src.manage_copyObjects("testcopy"))\n # After a copy/paste, they should *both* have a copy\n- self.assertTrue(hasattr(aq_base(src), \'testcopy\'))\n- self.assertTrue(hasattr(aq_base(dest), \'testcopy\'))\n+ self.assertTrue(hasattr(aq_base(src), "testcopy"))\n+ self.assertTrue(hasattr(aq_base(dest), "testcopy"))\n \n def testCutMemberContent(self):\n- self.login(\'user1\')\n- src = self.membership.getHomeFolder(\'user1\')\n- src.invokeFactory(\'Document\', id=\'testcut\')\n+ self.login("user1")\n+ src = self.membership.getHomeFolder("user1")\n+ src.invokeFactory("Document", id="testcut")\n \n # We need to commit here so that _p_jar isn\'t None and move\n # will work\n transaction.savepoint(optimistic=True)\n \n- src.invokeFactory(\'Folder\', id=\'dest\')\n+ src.invokeFactory("Folder", id="dest")\n dest = src.dest\n- dest.manage_pasteObjects(src.manage_cutObjects(\'testcut\'))\n+ dest.manage_pasteObjects(src.manage_cutObjects("testcut"))\n \n # After a cut/paste, only destination has a copy\n- self.assertFalse(hasattr(aq_base(src), \'testcut\'))\n- self.assertTrue(hasattr(aq_base(dest), \'testcut\'))\n+ self.assertFalse(hasattr(aq_base(src), "testcut"))\n+ self.assertTrue(hasattr(aq_base(dest), "testcut"))\n \n def testCutOtherMemberContent(self):\n- self.login(\'user1\')\n- src = self.membership.getHomeFolder(\'user1\')\n- src.invokeFactory(\'Document\', id=\'testcut\')\n+ self.login("user1")\n+ src = self.membership.getHomeFolder("user1")\n+ src.invokeFactory("Document", id="testcut")\n \n # We need to commit here so that _p_jar isn\'t None and move\n # will work\n transaction.savepoint(optimistic=True)\n \n- self.login(\'user2\')\n- self.assertRaises(Unauthorized, src.restrictedTraverse,\n- \'manage_cutObjects\')\n+ self.login("user2")\n+ self.assertRaises(Unauthorized, src.restrictedTraverse, "manage_cutObjects")\n \n def test_Bug2183_PastingIntoFolderFailsForNotAllowedContentTypes(self):\n # Test fix for http://dev.plone.org/plone/ticket/2183\n # The fix itself is in CMFCore.PortalFolder, not Plone\n \n # add the document to be copy and pasted later\n- self.folder.invokeFactory(\'Document\', \'doc\')\n+ self.folder.invokeFactory("Document", "doc")\n \n # add the folder where we try to paste the document later\n- self.folder.invokeFactory(\'Folder\', \'subfolder\')\n+ self.folder.invokeFactory("Folder", "subfolder")\n subfolder = self.folder.subfolder\n \n # now disallow adding Document globaly\n@@ -117,7 +115,7 @@ def test_Bug2183_PastingIntoFolderFailsForNotAllowedContentTypes(self):\n self.assertRaises(\n ValueError,\n subfolder.manage_pasteObjects,\n- self.folder.manage_copyObjects(ids=[\'doc\'])\n+ self.folder.manage_copyObjects(ids=["doc"]),\n )\n \n def test_Bug2183_PastingIntoPortalFailsForNotAllowedContentTypes(self):\n@@ -125,21 +123,21 @@ def test_Bug2183_PastingIntoPortalFailsForNotAllowedContentTypes(self):\n # The fix itself is in CMFCore.PortalFolder, not Plone\n \n # add the document to be copy and pasted later\n- self.folder.invokeFactory(\'Document\', \'doc\')\n+ self.folder.invokeFactory("Document", "doc")\n \n # now disallow adding Document globaly\n types = self.portal.portal_types\n types.Document.manage_changeProperties(global_allow=0)\n \n # need to be manager to paste into portal\n- self.setRoles([\'Manager\'])\n+ self.setRoles(["Manager"])\n \n # copy and pasting the object into the portal should raise\n # a ValueError.\n self.assertRaises(\n ValueError,\n self.portal.manage_pasteObjects,\n- self.folder.manage_copyObjects(ids=[\'doc\'])\n+ self.folder.manage_copyObjects(ids=["doc"]),\n )\n \n \n@@ -151,9 +149,9 @@ class CutPasteFailureTests(PloneTestCase):\n """See https://dev.plone.org/ticket/9365"""\n \n def afterSetUp(self):\n- self.folder.invokeFactory(\'Folder\', id=\'source-folder\')\n- self.folder.invokeFactory(\'Folder\', id=\'destination-folder\')\n- self.folder[\'source-folder\'].invokeFactory(\'Document\', id=\'doc\')\n+ self.folder.invokeFactory("Folder", id="source-folder")\n+ self.folder.invokeFactory("Folder", id="destination-folder")\n+ self.folder["source-folder"].invokeFactory("Document", id="doc")\n \n def testObject_pasteUncommitOnException(self):\n """Ensure that pasted objects aren\'t commited if an IObjectMovedEvent raises an exception.\n@@ -163,11 +161,11 @@ def testObject_pasteUncommitOnException(self):\n provideHandler(failingEventHandler, [IContentish, IObjectMovedEvent])\n try:\n browser = self.getBrowser()\n- browser.open(self.folder[\'source-folder\'][\'doc\'].absolute_url())\n- browser.getLink(\'Cut\').click()\n- browser.open(self.folder[\'destination-folder\'].absolute_url())\n+ browser.open(self.folder["source-folder"]["doc"].absolute_url())\n+ browser.getLink("Cut").click()\n+ browser.open(self.folder["destination-folder"].absolute_url())\n try:\n- browser.getLink(\'Paste\').click()\n+ browser.getLink("Paste").click()\n except HTTPError:\n # a HTTP 500 Server error is currently expected,\n # unless we find a better way to abort the\n@@ -175,24 +173,25 @@ def testObject_pasteUncommitOnException(self):\n pass\n \n # test if document is not moved\n- self.assertTrue(\'doc\' in self.folder[\'source-folder\'])\n- self.assertFalse(\'doc\' in self.folder[\'destination-folder\'])\n+ self.assertTrue("doc" in self.folder["source-folder"])\n+ self.assertFalse("doc" in self.folder["destination-folder"])\n \n finally:\n # unregister event handler\n getGlobalSiteManager().unregisterHandler(\n- failingEventHandler, [IContentish, IObjectMovedEvent])\n+ failingEventHandler, [IContentish, IObjectMovedEvent]\n+ )\n \n def testFolder_pasteUncommitOnException(self):\n # register event handler\n provideHandler(failingEventHandler, [IContentish, IObjectMovedEvent])\n try:\n browser = self.getBrowser()\n- browser.open(self.folder[\'source-folder\'][\'doc\'].absolute_url())\n- browser.getLink(\'Cut\').click()\n- browser.open(self.folder[\'destination-folder\'].absolute_url())\n+ browser.open(self.folder["source-folder"]["doc"].absolute_url())\n+ browser.getLink("Cut").click()\n+ browser.open(self.folder["destination-folder"].absolute_url())\n try:\n- browser.getLink(\'Paste\').click()\n+ browser.getLink("Paste").click()\n except HTTPError:\n # a HTTP 500 Server error is currently expected,\n # unless we find a better way to abort the\n@@ -200,10 +199,11 @@ def testFolder_pasteUncommitOnException(self):\n pass\n \n # test if document is not moved\n- self.assertTrue(\'doc\' in self.folder[\'source-folder\'])\n- self.assertFalse(\'doc\' in self.folder[\'destination-folder\'])\n+ self.assertTrue("doc" in self.folder["source-folder"])\n+ self.assertFalse("doc" in self.folder["destination-folder"])\n \n finally:\n # unregister event handler\n getGlobalSiteManager().unregisterHandler(\n- failingEventHandler, [IContentish, IObjectMovedEvent])\n+ failingEventHandler, [IContentish, IObjectMovedEvent]\n+ )\ndiff --git a/Products/CMFPlone/tests/testDateIndexRanges.py b/Products/CMFPlone/tests/testDateIndexRanges.py\nindex 1028b54c00..780a21bf31 100644\n--- a/Products/CMFPlone/tests/testDateIndexRanges.py\n+++ b/Products/CMFPlone/tests/testDateIndexRanges.py\n@@ -3,10 +3,9 @@\n \n \n class TestDateIndexRanges(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n- self.folder.invokeFactory(\'Document\', \'doc1\', title=\'Foo\')\n+ self.folder.invokeFactory("Document", "doc1", title="Foo")\n \n def testHiWatermark(self):\n self.folder.doc1.setExpirationDate(DateTime(4008, 0))\n@@ -15,11 +14,11 @@ def testHiWatermark(self):\n def testOverflow(self):\n self.folder.doc1.setExpirationDate(DateTime(4009, 0))\n # No OverflowError due to monkey patch\n- #self.assertRaises(OverflowError, self.folder.doc1.reindexObject)\n+ # self.assertRaises(OverflowError, self.folder.doc1.reindexObject)\n self.folder.doc1.reindexObject()\n \n def testDRIOverflow(self):\n self.folder.doc1.setEffectiveDate(DateTime(4009, 0))\n # No OverflowError due to monkey patch\n- #self.assertRaises(OverflowError, self.folder.doc1.reindexObject)\n+ # self.assertRaises(OverflowError, self.folder.doc1.reindexObject)\n self.folder.doc1.reindexObject()\ndiff --git a/Products/CMFPlone/tests/testDateTimeIntegration.py b/Products/CMFPlone/tests/testDateTimeIntegration.py\nindex b3bafc9503..f9cfe63dc4 100644\n--- a/Products/CMFPlone/tests/testDateTimeIntegration.py\n+++ b/Products/CMFPlone/tests/testDateTimeIntegration.py\n@@ -15,42 +15,43 @@\n \n \n class DateTimeTests(PloneTestCase):\n-\n def testModificationDate(self):\n obj = self.folder\n before = DateTime()\n notify(ObjectModifiedEvent(obj))\n after = DateTime()\n- modified = obj.ModificationDate() # the string representation...\n- modified = DateTime(modified) # is usually parsed again in Plone\n- self.assertTrue(int(before) <= int(modified) <= int(after),\n- (before, modified, after))\n+ modified = obj.ModificationDate() # the string representation...\n+ modified = DateTime(modified) # is usually parsed again in Plone\n+ self.assertTrue(\n+ int(before) <= int(modified) <= int(after), (before, modified, after)\n+ )\n \n def testCreationDate(self):\n before = DateTime()\n- obj = self.folder[self.folder.invokeFactory(\'Document\', \'foo\')]\n+ obj = self.folder[self.folder.invokeFactory("Document", "foo")]\n after = DateTime()\n- creation = obj.CreationDate() # the string representation...\n- creation = DateTime(creation) # is usually parsed again in Plone\n- self.assertTrue(int(before) <= int(creation) <= int(after),\n- (before, creation, after))\n+ creation = obj.CreationDate() # the string representation...\n+ creation = DateTime(creation) # is usually parsed again in Plone\n+ self.assertTrue(\n+ int(before) <= int(creation) <= int(after), (before, creation, after)\n+ )\n \n def testEffectiveDate(self):\n obj = self.folder\n- date = DateTime() + 365 # expire one year from today\n- date = DateTime(date.ISO8601()) # but strip off milliseconds\n+ date = DateTime() + 365 # expire one year from today\n+ date = DateTime(date.ISO8601()) # but strip off milliseconds\n obj.setEffectiveDate(date)\n notify(ObjectModifiedEvent(obj))\n- effective = obj.EffectiveDate() # the string representation...\n- effective = DateTime(effective) # is usually parsed again in Plone\n+ effective = obj.EffectiveDate() # the string representation...\n+ effective = DateTime(effective) # is usually parsed again in Plone\n self.assertTrue(date.equalTo(effective), (date, effective))\n \n def testExpirationDate(self):\n obj = self.folder\n- date = DateTime() + 365 # expire one year from today\n- date = DateTime(date.ISO8601()) # but strip off milliseconds\n+ date = DateTime() + 365 # expire one year from today\n+ date = DateTime(date.ISO8601()) # but strip off milliseconds\n obj.setExpirationDate(date)\n notify(ObjectModifiedEvent(obj))\n- expired = obj.ExpirationDate() # the string representation...\n- expired = DateTime(expired) # is usually parsed again in Plone\n+ expired = obj.ExpirationDate() # the string representation...\n+ expired = DateTime(expired) # is usually parsed again in Plone\n self.assertTrue(date.equalTo(expired), (date, expired))\ndiff --git a/Products/CMFPlone/tests/testEmailLogin.py b/Products/CMFPlone/tests/testEmailLogin.py\nindex 0e12786f3c..87dc5ecaf3 100644\n--- a/Products/CMFPlone/tests/testEmailLogin.py\n+++ b/Products/CMFPlone/tests/testEmailLogin.py\n@@ -11,11 +11,9 @@\n \n \n class TestEmailLogin(PloneTestCase.PloneTestCase):\n-\n def testUseEmailSetting(self):\n registry = getUtility(IRegistry)\n- security_settings = registry.forInterface(\n- ISecuritySchema, prefix=\'plone\')\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n \n self.assertFalse(security_settings.use_email_as_login)\n \n@@ -23,23 +21,23 @@ def testSetOwnLoginName(self):\n memship = self.portal.portal_membership\n users = self.portal.acl_users.source_users\n member = memship.getAuthenticatedMember()\n- self.assertEqual(users.getLoginForUserId(PloneTestCase.default_user),\n- \'test-user\')\n- set_own_login_name(member, \'maurits\')\n- self.assertEqual(users.getLoginForUserId(PloneTestCase.default_user),\n- \'maurits\')\n+ self.assertEqual(\n+ users.getLoginForUserId(PloneTestCase.default_user), "test-user"\n+ )\n+ set_own_login_name(member, "maurits")\n+ self.assertEqual(users.getLoginForUserId(PloneTestCase.default_user), "maurits")\n \n def testSetLoginNameOfOther(self):\n memship = self.portal.portal_membership\n- memship.addMember(\'maurits\', TEST_USER_PASSWORD, [], [])\n- member = memship.getMemberById(\'maurits\')\n- self.assertRaises(Unauthorized, set_own_login_name, member, \'vanrees\')\n+ memship.addMember("maurits", TEST_USER_PASSWORD, [], [])\n+ member = memship.getMemberById("maurits")\n+ self.assertRaises(Unauthorized, set_own_login_name, member, "vanrees")\n # The admin *should* be able to change the login name of\n # another user. See http://dev.plone.org/plone/ticket/11255\n self.loginAsPortalOwner()\n- set_own_login_name(member, \'vanrees\')\n+ set_own_login_name(member, "vanrees")\n users = self.portal.acl_users.source_users\n- self.assertEqual(users.getLoginForUserId(\'maurits\'), \'vanrees\')\n+ self.assertEqual(users.getLoginForUserId("maurits"), "vanrees")\n \n def testAdminSetOwnLoginName(self):\n memship = self.portal.portal_membership\n@@ -48,48 +46,45 @@ def testAdminSetOwnLoginName(self):\n # We are not allowed to change a user at the root zope level.\n # A KeyError is raised, or possibly in later Plone versions a\n # ValueError, so we simply go for an Exception.\n- self.assertRaises(Exception, set_own_login_name, member, \'vanrees\')\n+ self.assertRaises(Exception, set_own_login_name, member, "vanrees")\n \n def testNormalMemberIdsAllowed(self):\n pattern = self.portal.portal_registration._ALLOWED_MEMBER_ID_PATTERN\n- self.assertTrue(pattern.match(\'maurits\'))\n- self.assertTrue(pattern.match(\'Maur1ts\'))\n+ self.assertTrue(pattern.match("maurits"))\n+ self.assertTrue(pattern.match("Maur1ts"))\n # PLIP9214: the next test actually passes with the original\n # pattern but fails with the new one as email addresses cannot\n # end in a number:\n # self.assertTrue(pattern.match(\'maurits76\'))\n- self.assertTrue(pattern.match(\'MAURITS\'))\n+ self.assertTrue(pattern.match("MAURITS"))\n \n def testEmailMemberIdsAllowed(self):\n registry = getUtility(IRegistry)\n- security_settings = registry.forInterface(\n- ISecuritySchema, prefix=\'plone\')\n+ security_settings = registry.forInterface(ISecuritySchema, prefix="plone")\n security_settings.use_email_as_login = True\n \n- registration = getToolByName(self.portal, \'portal_registration\')\n+ registration = getToolByName(self.portal, "portal_registration")\n pattern = self.portal.portal_registration._ALLOWED_MEMBER_ID_PATTERN\n # Normal user ids are still allowed, even when using the email\n # address as login name.\n- self.assertTrue(pattern.match(\'joe\'))\n- self.assertTrue(registration.isMemberIdAllowed(\'joe\'))\n+ self.assertTrue(pattern.match("joe"))\n+ self.assertTrue(registration.isMemberIdAllowed("joe"))\n # Some normal email addresses\n- self.assertTrue(pattern.match(\'user@example.org\'))\n- self.assertTrue(registration.isMemberIdAllowed(\'user@example.org\'))\n- self.assertTrue(pattern.match(\'user123@example.org\'))\n- self.assertTrue(registration.isMemberIdAllowed(\'user123@example.org\'))\n- self.assertTrue(pattern.match(\'user.name@example.org\'))\n- self.assertTrue(\n- registration.isMemberIdAllowed(\'user.name@example.org\'))\n+ self.assertTrue(pattern.match("user@example.org"))\n+ self.assertTrue(registration.isMemberIdAllowed("user@example.org"))\n+ self.assertTrue(pattern.match("user123@example.org"))\n+ self.assertTrue(registration.isMemberIdAllowed("user123@example.org"))\n+ self.assertTrue(pattern.match("user.name@example.org"))\n+ self.assertTrue(registration.isMemberIdAllowed("user.name@example.org"))\n # Strange, but valid as id:\n- self.assertTrue(pattern.match(\'no.address@example\'))\n- self.assertTrue(registration.isMemberIdAllowed(\'no.address@example\'))\n+ self.assertTrue(pattern.match("no.address@example"))\n+ self.assertTrue(registration.isMemberIdAllowed("no.address@example"))\n # http://dev.plone.org/ticket/11616 mentions some non-standard\n # email addresses.\n # A plus sign in the id gives problems in some parts of the\n # UI, so we do not allow it.\n- self.assertFalse(pattern.match(\'user+test@example.org\'))\n- self.assertFalse(\n- registration.isMemberIdAllowed(\'user+test@example.org\'))\n+ self.assertFalse(pattern.match("user+test@example.org"))\n+ self.assertFalse(registration.isMemberIdAllowed("user+test@example.org"))\n # An apostrophe also sounds like a bad idea to use in an id,\n # though this is a valid email address:\n self.assertFalse(pattern.match("o\'hara@example.org"))\n@@ -105,12 +100,12 @@ def test_get_member_by_login_name(self):\n self.assertEqual(member.id, found.id)\n \n # Change the login name:\n- set_own_login_name(member, \'vanrees\')\n+ set_own_login_name(member, "vanrees")\n # A member with this user name is still returned:\n found = get_member_by_login_name(context, PloneTestCase.default_user)\n self.assertEqual(member.id, found.id)\n # With the changed login name we can find the member:\n- found = get_member_by_login_name(context, \'vanrees\')\n+ found = get_member_by_login_name(context, "vanrees")\n self.assertEqual(member.id, found.id)\n \n # Demonstrate that we can find other members than just the\ndiff --git a/Products/CMFPlone/tests/testExternalEditorEnabled.py b/Products/CMFPlone/tests/testExternalEditorEnabled.py\nindex 5333d831e4..81618bb5f0 100644\n--- a/Products/CMFPlone/tests/testExternalEditorEnabled.py\n+++ b/Products/CMFPlone/tests/testExternalEditorEnabled.py\n@@ -12,31 +12,32 @@\n HAS_EXTERNAL_EDITOR = True\n \n \n-@unittest.skipIf(not HAS_EXTERNAL_EDITOR, \'requires Products.ExternalEditor\')\n+@unittest.skipIf(not HAS_EXTERNAL_EDITOR, "requires Products.ExternalEditor")\n class TestExternalEditorEnabled(PloneTestCase.PloneTestCase):\n- \'\'\'Tests the externalEditorEnabled script\'\'\'\n+ """Tests the externalEditorEnabled script"""\n \n def afterSetUp(self):\n PloneTestCase.PloneTestCase.afterSetUp(self)\n- self.folder.invokeFactory(\'Document\', \'doc\')\n+ self.folder.invokeFactory("Document", "doc")\n self.doc = self.folder.doc\n- self.folder.invokeFactory(\'Folder\', \'folder2\')\n+ self.folder.invokeFactory("Folder", "folder2")\n self.folder = self.folder.folder2\n- self.portal.acl_users._doAddUser(\'user1\', TEST_USER_PASSWORD, [\'Member\'], [])\n+ self.portal.acl_users._doAddUser("user1", TEST_USER_PASSWORD, ["Member"], [])\n self.mtool = self.portal.portal_membership\n member = self.mtool.getAuthenticatedMember()\n- member.setMemberProperties({\'ext_editor\': 1})\n+ member.setMemberProperties({"ext_editor": 1})\n \n- self.lockbody = (\'\\n\'\n- \'\\n\'\n- \' \\n\'\n- \' \\n\'\n- \' infinity \\n\'\n- \' \\n\'\n- \' Zope External Editor \\n\'\n- \' \\n\'\n- \' \'\n- )\n+ self.lockbody = (\n+ \'\\n\'\n+ \'\\n\'\n+ " \\n"\n+ " \\n"\n+ " infinity \\n"\n+ " \\n"\n+ " Zope External Editor \\n"\n+ " \\n"\n+ " "\n+ )\n \n def testFailForAnonymous(self):\n self.assertTrue(self.doc.externalEditorEnabled())\n@@ -46,7 +47,7 @@ def testFailForAnonymous(self):\n def testFailOnDisabledMemberProperty(self):\n self.assertTrue(self.doc.externalEditorEnabled())\n member = self.mtool.getAuthenticatedMember()\n- member.setMemberProperties({\'ext_editor\': 0})\n+ member.setMemberProperties({"ext_editor": 0})\n self.assertFalse(self.doc.externalEditorEnabled())\n \n def testFailOnUnSupportedObjects(self):\n@@ -54,14 +55,13 @@ def testFailOnUnSupportedObjects(self):\n self.assertFalse(self.folder.externalEditorEnabled())\n \n def testFailWithoutUseExtEditPermission(self):\n- self.portal.manage_permission(\'Use external editor\',\n- (\'Owner\', \'Manager\'), 0)\n- self.login(\'user1\')\n+ self.portal.manage_permission("Use external editor", ("Owner", "Manager"), 0)\n+ self.login("user1")\n self.assertFalse(self.doc.externalEditorEnabled())\n \n def testFailWhenObjectIsLocked(self):\n # Should not show if someone already has a webdav lock on the object\n- self.doc.REQUEST.set(\'BODY\', self.lockbody)\n+ self.doc.REQUEST.set("BODY", self.lockbody)\n self.doc.LOCK(self.doc.REQUEST, self.doc.REQUEST.RESPONSE)\n self.assertFalse(self.doc.externalEditorEnabled())\n self.doc.wl_clearLocks()\n@@ -69,11 +69,11 @@ def testFailWhenObjectIsLocked(self):\n \n def testExternalEditorUsesZemExtensionForOSX(self):\n self.doc.external_edit()\n- redirect = self.doc.REQUEST.RESPONSE.headers[\'location\']\n- self.assertTrue(redirect.endswith(\'doc\'))\n+ redirect = self.doc.REQUEST.RESPONSE.headers["location"]\n+ self.assertTrue(redirect.endswith("doc"))\n \n # if Mac OS X in the user agent, add a .zem extension\n- self.doc.REQUEST.environ[\'HTTP_USER_AGENT\'] = \'Mac OS X\'\n+ self.doc.REQUEST.environ["HTTP_USER_AGENT"] = "Mac OS X"\n self.doc.external_edit()\n- redirect = self.doc.REQUEST.RESPONSE.headers[\'location\']\n- self.assertTrue(redirect.endswith(\'.zem?macosx=1\'))\n+ redirect = self.doc.REQUEST.RESPONSE.headers["location"]\n+ self.assertTrue(redirect.endswith(".zem?macosx=1"))\ndiff --git a/Products/CMFPlone/tests/testIImagingSchema.py b/Products/CMFPlone/tests/testIImagingSchema.py\nindex 6f404df211..357748af42 100644\n--- a/Products/CMFPlone/tests/testIImagingSchema.py\n+++ b/Products/CMFPlone/tests/testIImagingSchema.py\n@@ -7,12 +7,11 @@\n \n \n class TestImagingSchemaTool(unittest.TestCase):\n-\n layer = PLONE_INTEGRATION_TESTING\n \n def test_AllowedSizes(self):\n registry = getUtility(IRegistry)\n- imaging_settings = registry.forInterface(IImagingSchema, prefix=\'plone\')\n+ imaging_settings = registry.forInterface(IImagingSchema, prefix="plone")\n \n # Ensure we can save the defaults back to the registry\n imaging_settings.allowed_sizes = imaging_settings.allowed_sizes\ndiff --git a/Products/CMFPlone/tests/testInterfaces.py b/Products/CMFPlone/tests/testInterfaces.py\nindex 46c1cb6afd..89ff62f9a9 100644\n--- a/Products/CMFPlone/tests/testInterfaces.py\n+++ b/Products/CMFPlone/tests/testInterfaces.py\n@@ -27,11 +27,10 @@\n \n \n def className(klass):\n- """ get the short class name """\n- if not isinstance(klass, (type, ClassType,\n- ExtensionClass, InterfaceClass)):\n+ """get the short class name"""\n+ if not isinstance(klass, (type, ClassType, ExtensionClass, InterfaceClass)):\n # Looks like an instance, get its class.\n- if hasattr(klass, \'__class__\'):\n+ if hasattr(klass, "__class__"):\n klass = klass.__class__\n return klass.__name__\n \n@@ -39,6 +38,7 @@ def className(klass):\n def dottedName(klass):\n return f"{klass.__module__}.{klass.__name__}"\n \n+\n # list of tests\n tests = []\n \n@@ -65,77 +65,93 @@ class InterfaceTest(TestCase):\n forcedImpl = () # class must implement this tuple of interfaces\n \n def interfaceImplementedByInstanceOf(self, klass, interface):\n- """ tests if the klass implements the interface in the right way """\n+ """tests if the klass implements the interface in the right way"""\n from zope.interface.exceptions import BrokenImplementation\n from zope.interface.exceptions import BrokenMethodImplementation\n from zope.interface.exceptions import DoesNotImplement\n from zope.interface.verify import verifyClass\n \n # is the class really implemented by the given interface?\n- self.assertTrue(interface.implementedBy(klass),\n- \'The class {} does not implement {}\'.format(dottedName(klass),\n- dottedName(interface)))\n+ self.assertTrue(\n+ interface.implementedBy(klass),\n+ "The class {} does not implement {}".format(\n+ dottedName(klass), dottedName(interface)\n+ ),\n+ )\n # verify if the implementation is correct\n try:\n verifyClass(interface, klass)\n- except (BrokenImplementation, DoesNotImplement,\n- BrokenMethodImplementation) as errmsg:\n- self.fail(\'The class %s does not implement %s correctly: \\n%s\'\n- % (dottedName(klass), dottedName(interface), errmsg))\n+ except (\n+ BrokenImplementation,\n+ DoesNotImplement,\n+ BrokenMethodImplementation,\n+ ) as errmsg:\n+ self.fail(\n+ "The class %s does not implement %s correctly: \\n%s"\n+ % (dottedName(klass), dottedName(interface), errmsg)\n+ )\n \n def interfaceImplementedBy(self, instance, interface):\n- """ tests if the instance implements the interface in the right way """\n+ """tests if the instance implements the interface in the right way"""\n from zope.interface.exceptions import BrokenImplementation\n from zope.interface.exceptions import BrokenMethodImplementation\n from zope.interface.exceptions import DoesNotImplement\n from zope.interface.verify import verifyObject\n \n # is the class really implemented by the given interface?\n- self.assertTrue(interface.providedBy(instance),\n- \'The instance of %s does not implement %s\'\n- % (dottedName(instance), dottedName(interface)))\n+ self.assertTrue(\n+ interface.providedBy(instance),\n+ "The instance of %s does not implement %s"\n+ % (dottedName(instance), dottedName(interface)),\n+ )\n # verify if the implementation is correct\n try:\n verifyObject(interface, instance)\n- except (BrokenImplementation,\n- DoesNotImplement,\n- BrokenMethodImplementation) as errmsg:\n+ except (\n+ BrokenImplementation,\n+ DoesNotImplement,\n+ BrokenMethodImplementation,\n+ ) as errmsg:\n self.fail(\n- \'The instance of %s does not implement %s correctly: \\n%s\'\n- % (dottedName(instance), dottedName(interface), errmsg))\n+ "The instance of %s does not implement %s correctly: \\n%s"\n+ % (dottedName(instance), dottedName(interface), errmsg)\n+ )\n \n def getImplementsOfInstanceOf(self, klass):\n- """ returns the interfaces implemented by the klass (flat)"""\n+ """returns the interfaces implemented by the klass (flat)"""\n return tuple(implementedBy(klass))\n \n def getImplementsOf(self, instance):\n- """ returns the interfaces implemented by the instance (flat)"""\n+ """returns the interfaces implemented by the instance (flat)"""\n return tuple(providedBy(instance))\n \n def doesImplementByInstanceOf(self, klass, interfaces):\n- """ make sure that the klass implements at least these interfaces"""\n+ """make sure that the klass implements at least these interfaces"""\n if type(interfaces) is not tuple:\n- interfaces = (interfaces)\n+ interfaces = interfaces\n impl = self.getImplementsOfInstanceOf(klass)\n for interface in interfaces:\n self.assertTrue(\n interface in impl,\n- \'The class {} does not implement {}\'.format(dottedName(klass),\n- dottedName(interface)))\n+ "The class {} does not implement {}".format(\n+ dottedName(klass), dottedName(interface)\n+ ),\n+ )\n \n def doesImplementBy(self, instance, interfaces):\n- """ make sure that the klass implements at least these interfaces"""\n+ """make sure that the klass implements at least these interfaces"""\n if type(interfaces) is not tuple:\n- interfaces = (interfaces)\n+ interfaces = interfaces\n impl = self.getImplementsOf(instance)\n for interface in interfaces:\n self.assertTrue(\n interface in impl,\n- \'The instance of %s does not implement %s\'\n- % (dottedName(instance), dottedName(interface)))\n+ "The instance of %s does not implement %s"\n+ % (dottedName(instance), dottedName(interface)),\n+ )\n \n def _testStuff(self):\n- """ test self.klass and self.instance """\n+ """test self.klass and self.instance"""\n if self.klass:\n if self.forcedImpl:\n self.doesImplementByInstanceOf(self.klass, self.forcedImpl)\n@@ -170,7 +186,7 @@ class zope_interface_test(TestCase):\n forcedImpl = () # class must implement this tuple of interfaces\n \n def interfaceImplementedBy(self, klass, interface):\n- """ tests if the klass implements the interface in the right way """\n+ """tests if the klass implements the interface in the right way"""\n \n from zope.interface.exceptions import BrokenImplementation\n from zope.interface.exceptions import BrokenMethodImplementation\n@@ -178,66 +194,87 @@ def interfaceImplementedBy(self, klass, interface):\n from zope.interface.verify import verifyClass\n \n # is the class really implemented by the given interface?\n- self.assertTrue(interface.implementedBy(klass),\n- \'The class {} does not implement {}\'.format(dottedName(klass),\n- dottedName(interface)))\n+ self.assertTrue(\n+ interface.implementedBy(klass),\n+ "The class {} does not implement {}".format(\n+ dottedName(klass), dottedName(interface)\n+ ),\n+ )\n # verify if the implementation is correct\n try:\n verifyClass(interface, klass)\n- except (BrokenImplementation, DoesNotImplement,\n- BrokenMethodImplementation) as errmsg:\n- self.fail(\'The class %s does not implement %s correctly: \\n%s\'\n- % (dottedName(klass), dottedName(interface), errmsg))\n+ except (\n+ BrokenImplementation,\n+ DoesNotImplement,\n+ BrokenMethodImplementation,\n+ ) as errmsg:\n+ self.fail(\n+ "The class %s does not implement %s correctly: \\n%s"\n+ % (dottedName(klass), dottedName(interface), errmsg)\n+ )\n \n def interfaceProvidedBy(self, instance, interface):\n- """ tests if the instance implements the interface in the right way """\n+ """tests if the instance implements the interface in the right way"""\n from zope.interface.exceptions import BrokenImplementation\n from zope.interface.exceptions import BrokenMethodImplementation\n from zope.interface.exceptions import DoesNotImplement\n from zope.interface.verify import verifyObject\n \n # is the class really implemented by the given interface?\n- self.assertTrue(interface.providedBy(instance),\n- \'The instance of {} does not provide {}\'.format(dottedName(instance),\n- dottedName(interface)))\n+ self.assertTrue(\n+ interface.providedBy(instance),\n+ "The instance of {} does not provide {}".format(\n+ dottedName(instance), dottedName(interface)\n+ ),\n+ )\n # verify if the implementation is correct\n try:\n verifyObject(interface, instance)\n- except (BrokenImplementation, DoesNotImplement,\n- BrokenMethodImplementation) as errmsg:\n- self.fail(\'The instance of %s does not provide %s correctly: \\n%s\'\n- % (dottedName(instance), dottedName(interface), errmsg))\n+ except (\n+ BrokenImplementation,\n+ DoesNotImplement,\n+ BrokenMethodImplementation,\n+ ) as errmsg:\n+ self.fail(\n+ "The instance of %s does not provide %s correctly: \\n%s"\n+ % (dottedName(instance), dottedName(interface), errmsg)\n+ )\n \n def getImplementedBy(self, klass):\n- """ returns the interfaces implemented by the klass (flat)"""\n+ """returns the interfaces implemented by the klass (flat)"""\n from zope.interface import implementedBy\n+\n return implementedBy(klass)\n \n def getProvidedBy(self, instance):\n- """ returns the interfaces implemented by the instance (flat)"""\n+ """returns the interfaces implemented by the instance (flat)"""\n from zope.interface import providedBy\n+\n return providedBy(instance)\n \n def doesImplementedBy(self, klass, interfaces):\n- """ make sure that the klass implements at least these interfaces"""\n+ """make sure that the klass implements at least these interfaces"""\n impl = self.getImplementedBy(klass)\n for interface in interfaces:\n self.assertTrue(\n interface in impl,\n- \'The class {} does not implement {}\'.format(dottedName(klass),\n- dottedName(interface)))\n+ "The class {} does not implement {}".format(\n+ dottedName(klass), dottedName(interface)\n+ ),\n+ )\n \n def doesProvidedBy(self, instance, interfaces):\n- """ make sure that the klass implements at least these interfaces"""\n+ """make sure that the klass implements at least these interfaces"""\n impl = self.getProvidedBy(instance)\n for interface in interfaces:\n self.assertTrue(\n interface in impl,\n- \'The instance of %s does not provide %s\'\n- % (dottedName(instance), dottedName(interface)))\n+ "The instance of %s does not provide %s"\n+ % (dottedName(instance), dottedName(interface)),\n+ )\n \n def _testStuff(self):\n- """ test self.klass and self.instance """\n+ """test self.klass and self.instance"""\n if self.klass:\n if self.forcedImpl:\n self.doesImplementedBy(self.klass, self.forcedImpl)\n@@ -259,10 +296,12 @@ def _testStuff(self):\n (ActionsTool, ()),\n (CatalogTool, ()),\n (MigrationTool, ()),\n- (PloneControlPanel, ()), (PloneConfiglet, ()),\n+ (PloneControlPanel, ()),\n+ (PloneConfiglet, ()),\n (PloneTool, ()),\n (PloneSite, ()),\n- (PropertiesTool, ()), (SimpleItemWithProperties, ()),\n+ (PropertiesTool, ()),\n+ (SimpleItemWithProperties, ()),\n (RegistrationTool, ()),\n (SkinsTool, ()),\n (TypesTool, ()),\n@@ -273,10 +312,11 @@ def _testStuff(self):\n for testClass in testClasses:\n klass, forcedImpl = testClass\n name = className(klass)\n- funcName = \'test%sInterface\' % name\n+ funcName = "test%sInterface" % name\n \n class KlassInterfaceTest(InterfaceTest):\n """ implementation for %s """ % name\n+\n klass = klass\n forcedImpl = forcedImpl\n \n@@ -286,6 +326,7 @@ class KlassInterfaceTest(InterfaceTest):\n \n class KlassInterfaceTest(zope_interface_test):\n """ implementation for %s """ % name\n+\n klass = klass\n forcedImpl = forcedImpl\n \ndiff --git a/Products/CMFPlone/tests/testMigrationTool.py b/Products/CMFPlone/tests/testMigrationTool.py\nindex 48f1647d16..342a0856d5 100644\n--- a/Products/CMFPlone/tests/testMigrationTool.py\n+++ b/Products/CMFPlone/tests/testMigrationTool.py\n@@ -5,31 +5,29 @@\n \n # Python 3 is only supported on 5.2+.\n # This means you can not upgrade from 5.1 or earlier.\n-START_PROFILE = \'5200\'\n+START_PROFILE = "5200"\n \n \n class TestMigrationTool(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n self.migration = getToolByName(self.portal, "portal_migration")\n self.setup = getToolByName(self.portal, "portal_setup")\n \n def testMigrationFinished(self):\n- self.assertEqual(self.migration.getInstanceVersion(),\n- self.migration.getFileSystemVersion(),\n- \'Migration failed\')\n+ self.assertEqual(\n+ self.migration.getInstanceVersion(),\n+ self.migration.getFileSystemVersion(),\n+ "Migration failed",\n+ )\n \n def testMigrationNeedsUpgrading(self):\n- self.assertFalse(self.migration.needUpgrading(),\n- \'Migration needs upgrading\')\n+ self.assertFalse(self.migration.needUpgrading(), "Migration needs upgrading")\n \n def testMigrationNeedsUpdateRole(self):\n- self.assertFalse(self.migration.needUpdateRole(),\n- \'Migration needs role update\')\n+ self.assertFalse(self.migration.needUpdateRole(), "Migration needs role update")\n \n def testMigrationNeedsRecatalog(self):\n- self.assertFalse(self.migration.needRecatalog(),\n- \'Migration needs recataloging\')\n+ self.assertFalse(self.migration.needRecatalog(), "Migration needs recataloging")\n \n def testListSetupUpgradeSteps(self):\n # There should be no upgrade steps from the current version\n@@ -42,27 +40,27 @@ def testListOwnUpgradeSteps(self):\n self.assertEqual(len(upgrades), 0)\n \n def testDoUpgrades(self):\n- self.setRoles([\'Manager\'])\n+ self.setRoles(["Manager"])\n self.setup.setLastVersionForProfile(_DEFAULT_PROFILE, START_PROFILE)\n upgrades = self.migration.listUpgrades()\n self.assertGreater(len(upgrades), 0)\n \n request = self.portal.REQUEST\n- request.form[\'profile_id\'] = _DEFAULT_PROFILE\n+ request.form["profile_id"] = _DEFAULT_PROFILE\n \n steps = []\n for upgrade in upgrades:\n if isinstance(upgrade, list):\n- steps.extend([s[\'id\'] for s in upgrade])\n+ steps.extend([s["id"] for s in upgrade])\n else:\n- steps.append(upgrade[\'id\'])\n+ steps.append(upgrade["id"])\n \n- request.form[\'upgrades\'] = steps\n+ request.form["upgrades"] = steps\n self.setup.manage_doUpgrades(request=request)\n \n # And we have reached our current profile version\n current = self.setup.getVersionForProfile(_DEFAULT_PROFILE)\n- current = tuple(current.split(\'.\'))\n+ current = tuple(current.split("."))\n last = self.setup.getLastVersionForProfile(_DEFAULT_PROFILE)\n self.assertEqual(last, current)\n \n@@ -71,13 +69,13 @@ def testDoUpgrades(self):\n self.assertEqual(len(upgrades), 0)\n \n def testUpgrade(self):\n- self.setRoles([\'Manager\'])\n+ self.setRoles(["Manager"])\n self.setup.setLastVersionForProfile(_DEFAULT_PROFILE, START_PROFILE)\n self.migration.upgrade()\n \n # And we have reached our current profile version\n current = self.setup.getVersionForProfile(_DEFAULT_PROFILE)\n- current = tuple(current.split(\'.\'))\n+ current = tuple(current.split("."))\n last = self.setup.getLastVersionForProfile(_DEFAULT_PROFILE)\n self.assertEqual(last, current)\n \n@@ -103,15 +101,21 @@ def afterSetUp(self):\n self.setup = getToolByName(self.portal, "portal_setup")\n \n def failing_upgrade(context):\n- raise AssertionError(\'Too new upgrade should not be run!\')\n+ raise AssertionError("Too new upgrade should not be run!")\n \n # Register a too new upgrade.\n fs_version = self.migration.getFileSystemVersion()\n new_version = str(int(fs_version) + 1)\n new_step = UpgradeStep(\n- \'Too new upgrade\', _DEFAULT_PROFILE,\n- fs_version, new_version,\n- \'\', failing_upgrade, None, \'1\')\n+ "Too new upgrade",\n+ _DEFAULT_PROFILE,\n+ fs_version,\n+ new_version,\n+ "",\n+ failing_upgrade,\n+ None,\n+ "1",\n+ )\n self.step_id = new_step.id\n _registerUpgradeStep(new_step)\n \n@@ -119,8 +123,8 @@ def beforeTearDown(self):\n # Remove the extra step from the upgrade registry,\n # otherwise this bleeds over into other tests.\n from Products.GenericSetup.upgrade import _upgrade_registry\n- profile_steps = _upgrade_registry.getUpgradeStepsForProfile(\n- _DEFAULT_PROFILE)\n+\n+ profile_steps = _upgrade_registry.getUpgradeStepsForProfile(_DEFAULT_PROFILE)\n profile_steps.pop(self.step_id, None)\n \n def testListUpgradeStepsNotTooNew(self):\n@@ -132,13 +136,13 @@ def testListUpgradeStepsNotTooNew(self):\n self.assertEqual(len(upgrades), 0)\n \n def testUpgrade(self):\n- self.setRoles([\'Manager\'])\n+ self.setRoles(["Manager"])\n self.setup.setLastVersionForProfile(_DEFAULT_PROFILE, START_PROFILE)\n self.migration.upgrade()\n \n # And we have reached our current profile version\n current = self.setup.getVersionForProfile(_DEFAULT_PROFILE)\n- current = tuple(current.split(\'.\'))\n+ current = tuple(current.split("."))\n last = self.setup.getLastVersionForProfile(_DEFAULT_PROFILE)\n self.assertEqual(last, current)\n \n@@ -148,57 +152,53 @@ def testUpgrade(self):\n \n \n class TestAddonList(PloneTestCase.PloneTestCase):\n-\n def test_addon_safe(self):\n from Products.CMFPlone.MigrationTool import Addon\n+\n addon = Addon(profile_id=_DEFAULT_PROFILE)\n self.assertTrue(addon.safe())\n- addon = Addon(profile_id=_DEFAULT_PROFILE,\n- check_module=\'Products.CMFPlone\')\n+ addon = Addon(profile_id=_DEFAULT_PROFILE, check_module="Products.CMFPlone")\n self.assertTrue(addon.safe())\n- addon = Addon(profile_id=_DEFAULT_PROFILE,\n- check_module=\'Products.CMFPlone.foobarbaz\')\n+ addon = Addon(\n+ profile_id=_DEFAULT_PROFILE, check_module="Products.CMFPlone.foobarbaz"\n+ )\n self.assertFalse(addon.safe())\n \n def test_addon_repr(self):\n from Products.CMFPlone.MigrationTool import Addon\n- addon = Addon(profile_id=\'foo\')\n- self.assertEqual(repr(addon), \'\')\n- self.assertEqual(str(addon), \'\')\n+\n+ addon = Addon(profile_id="foo")\n+ self.assertEqual(repr(addon), "")\n+ self.assertEqual(str(addon), "")\n \n def test_upgrade_all(self):\n from Products.CMFPlone.MigrationTool import Addon\n from Products.CMFPlone.MigrationTool import AddonList\n \n # real ones:\n- cmfeditions = Addon(profile_id=\'Products.CMFEditions:CMFEditions\')\n- discussion = Addon(profile_id=\'plone.app.discussion:default\')\n+ cmfeditions = Addon(profile_id="Products.CMFEditions:CMFEditions")\n+ discussion = Addon(profile_id="plone.app.discussion:default")\n # real one with failing check_module:\n- dexterity = Addon(profile_id=\'plone.app.dexterity:default\',\n- check_module=\'no.such.module\')\n+ dexterity = Addon(\n+ profile_id="plone.app.dexterity:default", check_module="no.such.module"\n+ )\n # non-existing one:\n- foo = Addon(profile_id=\'foo\')\n- addonlist = AddonList([\n- cmfeditions,\n- discussion,\n- dexterity,\n- foo\n- ])\n+ foo = Addon(profile_id="foo")\n+ addonlist = AddonList([cmfeditions, discussion, dexterity, foo])\n # Calling it should give no errors.\n addonlist.upgrade_all(self.portal)\n \n # Get the last CMFEditions profile version, as that will be\n # the only one that gets upgraded during the second upgrade.\n setup = getToolByName(self.portal, "portal_setup")\n- cmfeditions_version = setup.getLastVersionForProfile(\n- cmfeditions.profile_id)\n+ cmfeditions_version = setup.getLastVersionForProfile(cmfeditions.profile_id)\n \n # Now mess with the profile versions.\n- setup.setLastVersionForProfile(cmfeditions.profile_id, \'2.0\')\n- setup.setLastVersionForProfile(dexterity.profile_id, \'0.1\')\n+ setup.setLastVersionForProfile(cmfeditions.profile_id, "2.0")\n+ setup.setLastVersionForProfile(dexterity.profile_id, "0.1")\n # \'unknown\' needs special handling, otherwise the version will\n # become a tuple (\'unknown\',):\n- setup._profile_upgrade_versions[discussion.profile_id] = \'unknown\'\n+ setup._profile_upgrade_versions[discussion.profile_id] = "unknown"\n \n # Run the upgrade again.\n addonlist.upgrade_all(self.portal)\n@@ -206,22 +206,20 @@ def test_upgrade_all(self):\n # Check the profile versions.\n # CMFEditions should be the last one:\n self.assertEqual(\n- setup.getLastVersionForProfile(cmfeditions.profile_id),\n- cmfeditions_version)\n+ setup.getLastVersionForProfile(cmfeditions.profile_id), cmfeditions_version\n+ )\n # We had set discussion to unknown, so it will not have been\n # upgraded:\n self.assertEqual(\n- setup.getLastVersionForProfile(discussion.profile_id),\n- \'unknown\')\n+ setup.getLastVersionForProfile(discussion.profile_id), "unknown"\n+ )\n # We had given dexterity a failing check_module, so it will\n # not have been upgraded:\n self.assertEqual(\n- setup.getLastVersionForProfile(dexterity.profile_id),\n- (\'0\', \'1\'))\n+ setup.getLastVersionForProfile(dexterity.profile_id), ("0", "1")\n+ )\n # The foo profile never existed:\n- self.assertEqual(\n- setup.getLastVersionForProfile(foo.profile_id),\n- \'unknown\')\n+ self.assertEqual(setup.getLastVersionForProfile(foo.profile_id), "unknown")\n \n def test_plone_addonlist_upgrade_all(self):\n # Test the actual filled addon list.\n@@ -229,9 +227,9 @@ def test_plone_addonlist_upgrade_all(self):\n \n # Several addons did not get fully upgraded in the past, which\n # is why this list was created.\n- cmfeditions_id = \'Products.CMFEditions:CMFEditions\'\n- discussion_id = \'plone.app.discussion:default\'\n- querystring_id = \'plone.app.querystring:default\'\n+ cmfeditions_id = "Products.CMFEditions:CMFEditions"\n+ discussion_id = "plone.app.discussion:default"\n+ querystring_id = "plone.app.querystring:default"\n # Note the current versions.\n setup = getToolByName(self.portal, "portal_setup")\n getversion = setup.getLastVersionForProfile\n@@ -239,15 +237,15 @@ def test_plone_addonlist_upgrade_all(self):\n discussion_version = getversion(discussion_id)\n querystring_version = getversion(querystring_id)\n # Check that they are not unknown\n- self.assertNotEqual(cmfeditions_version, \'unknown\')\n- self.assertNotEqual(discussion_version, \'unknown\')\n- self.assertNotEqual(querystring_version, \'unknown\')\n+ self.assertNotEqual(cmfeditions_version, "unknown")\n+ self.assertNotEqual(discussion_version, "unknown")\n+ self.assertNotEqual(querystring_version, "unknown")\n # So let\'s mess with some profile versions. We get some older\n # versions that really exist.\n setversion = setup.setLastVersionForProfile\n- setversion(cmfeditions_id, \'2.0\')\n- setversion(discussion_id, \'100\')\n- setversion(querystring_id, \'7\')\n+ setversion(cmfeditions_id, "2.0")\n+ setversion(discussion_id, "100")\n+ setversion(querystring_id, "7")\n # Check that it worked, that the profile versions really are\n # different.\n self.assertNotEqual(cmfeditions_version, getversion(cmfeditions_id))\ndiff --git a/Products/CMFPlone/tests/testNavTree.py b/Products/CMFPlone/tests/testNavTree.py\nindex 1b4997b48a..40dc220684 100644\n--- a/Products/CMFPlone/tests/testNavTree.py\n+++ b/Products/CMFPlone/tests/testNavTree.py\n@@ -20,7 +20,7 @@ class DummyNonStructuralFolder(CatalogAware, PortalFolderBase):\n \n \n class TestFolderTree(PloneTestCase.PloneTestCase):\n- \'\'\'Test the basic buildFolderTree method\'\'\'\n+ """Test the basic buildFolderTree method"""\n \n def afterSetUp(self):\n self.populateSite()\n@@ -28,535 +28,582 @@ def afterSetUp(self):\n \n def populateSite(self):\n """\n- Portal\n- +-doc1\n- +-doc2\n- +-doc3\n- +-folder1\n- +-doc11\n- +-doc12\n- +-doc13\n- +-link1\n- +-folder2\n- +-doc21\n- +-doc22\n- +-doc23\n- +-file21\n- +-folder21\n- +-doc211\n- +-doc212\n+ Portal\n+ +-doc1\n+ +-doc2\n+ +-doc3\n+ +-folder1\n+ +-doc11\n+ +-doc12\n+ +-doc13\n+ +-link1\n+ +-folder2\n+ +-doc21\n+ +-doc22\n+ +-doc23\n+ +-file21\n+ +-folder21\n+ +-doc211\n+ +-doc212\n """\n- self.setRoles([\'Manager\'])\n+ self.setRoles(["Manager"])\n \n for item in self.portal.getFolderContents():\n self.portal._delObject(item.getId)\n \n- self.portal.invokeFactory(\'Document\', \'doc1\')\n- self.portal.invokeFactory(\'Document\', \'doc2\')\n- self.portal.invokeFactory(\'Document\', \'doc3\')\n- self.portal.invokeFactory(\'Folder\', \'folder1\')\n- self.portal.invokeFactory(\'Link\', \'link1\')\n- self.portal.link1.remoteUrl = \'http://plone.org\'\n+ self.portal.invokeFactory("Document", "doc1")\n+ self.portal.invokeFactory("Document", "doc2")\n+ self.portal.invokeFactory("Document", "doc3")\n+ self.portal.invokeFactory("Folder", "folder1")\n+ self.portal.invokeFactory("Link", "link1")\n+ self.portal.link1.remoteUrl = "http://plone.org"\n self.portal.link1.reindexObject()\n- folder1 = getattr(self.portal, \'folder1\')\n- folder1.invokeFactory(\'Document\', \'doc11\')\n- folder1.invokeFactory(\'Document\', \'doc12\')\n- folder1.invokeFactory(\'Document\', \'doc13\')\n- self.portal.invokeFactory(\'Folder\', \'folder2\')\n- folder2 = getattr(self.portal, \'folder2\')\n- folder2.invokeFactory(\'Document\', \'doc21\')\n- folder2.invokeFactory(\'Document\', \'doc22\')\n- folder2.invokeFactory(\'Document\', \'doc23\')\n- folder2.invokeFactory(\'File\', \'file21\')\n- folder2.invokeFactory(\'Folder\', \'folder21\')\n- folder21 = getattr(folder2, \'folder21\')\n- folder21.invokeFactory(\'Document\', \'doc211\')\n- folder21.invokeFactory(\'Document\', \'doc212\')\n- self.setRoles([\'Member\'])\n+ folder1 = getattr(self.portal, "folder1")\n+ folder1.invokeFactory("Document", "doc11")\n+ folder1.invokeFactory("Document", "doc12")\n+ folder1.invokeFactory("Document", "doc13")\n+ self.portal.invokeFactory("Folder", "folder2")\n+ folder2 = getattr(self.portal, "folder2")\n+ folder2.invokeFactory("Document", "doc21")\n+ folder2.invokeFactory("Document", "doc22")\n+ folder2.invokeFactory("Document", "doc23")\n+ folder2.invokeFactory("File", "file21")\n+ folder2.invokeFactory("Folder", "folder21")\n+ folder21 = getattr(folder2, "folder21")\n+ folder21.invokeFactory("Document", "doc211")\n+ folder21.invokeFactory("Document", "doc212")\n+ self.setRoles(["Member"])\n \n # Get from the root, filters\n \n def testGetFromRoot(self):\n- tree = buildFolderTree(self.portal)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(self.portal)["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 6)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n- self.assertEqual(tree[3][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[3][\'children\']), 3)\n- self.assertEqual(tree[3][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[3][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder1/doc12\')\n- self.assertEqual(tree[3][\'children\'][2][\n- \'item\'].getPath(), rootPath + \'/folder1/doc13\')\n- self.assertEqual(tree[4][\'item\'].getPath(), rootPath + \'/link1\')\n- self.assertEqual(tree[5][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[5][\'children\']), 5)\n- self.assertEqual(tree[5][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/doc21\')\n- self.assertEqual(tree[5][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder2/doc22\')\n- self.assertEqual(tree[5][\'children\'][2][\n- \'item\'].getPath(), rootPath + \'/folder2/doc23\')\n- self.assertEqual(tree[5][\'children\'][3][\n- \'item\'].getPath(), rootPath + \'/folder2/file21\')\n- self.assertEqual(tree[5][\'children\'][4][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21\')\n- self.assertEqual(len(tree[5][\'children\'][4][\'children\']), 2)\n- self.assertEqual(tree[5][\'children\'][4][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21/doc211\')\n- self.assertEqual(tree[5][\'children\'][4][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21/doc212\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[3]["children"]), 3)\n+ self.assertEqual(\n+ tree[3]["children"][0]["item"].getPath(), rootPath + "/folder1/doc11"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][1]["item"].getPath(), rootPath + "/folder1/doc12"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][2]["item"].getPath(), rootPath + "/folder1/doc13"\n+ )\n+ self.assertEqual(tree[4]["item"].getPath(), rootPath + "/link1")\n+ self.assertEqual(tree[5]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[5]["children"]), 5)\n+ self.assertEqual(\n+ tree[5]["children"][0]["item"].getPath(), rootPath + "/folder2/doc21"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][1]["item"].getPath(), rootPath + "/folder2/doc22"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][2]["item"].getPath(), rootPath + "/folder2/doc23"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][3]["item"].getPath(), rootPath + "/folder2/file21"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][4]["item"].getPath(), rootPath + "/folder2/folder21"\n+ )\n+ self.assertEqual(len(tree[5]["children"][4]["children"]), 2)\n+ self.assertEqual(\n+ tree[5]["children"][4]["children"][0]["item"].getPath(),\n+ rootPath + "/folder2/folder21/doc211",\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][4]["children"][1]["item"].getPath(),\n+ rootPath + "/folder2/folder21/doc212",\n+ )\n \n def testGetFromRootWithSpecifiedRoot(self):\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n strategy = NavtreeStrategyBase()\n- strategy.rootPath = rootPath + \'/folder1\'\n- tree = buildFolderTree(self.portal, strategy=strategy)[\'children\']\n+ strategy.rootPath = rootPath + "/folder1"\n+ tree = buildFolderTree(self.portal, strategy=strategy)["children"]\n self.assertEqual(len(tree), 3)\n- self.assertEqual(tree[0][\'item\'].getPath(),\n- rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[1][\'item\'].getPath(),\n- rootPath + \'/folder1/doc12\')\n- self.assertEqual(tree[2][\'item\'].getPath(),\n- rootPath + \'/folder1/doc13\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder1/doc11")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/folder1/doc12")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/folder1/doc13")\n \n def testGetFromRootWithNodeFilter(self):\n class Strategy(NavtreeStrategyBase):\n-\n def nodeFilter(self, node):\n- return (\'doc\' not in node[\'item\'].getId)\n- tree = buildFolderTree(self.portal, strategy=Strategy())[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ return "doc" not in node["item"].getId\n+\n+ tree = buildFolderTree(self.portal, strategy=Strategy())["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 3)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[0][\'children\']), 0)\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/link1\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[2][\'children\']), 2)\n- self.assertEqual(tree[2][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/file21\')\n- self.assertEqual(tree[2][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21\')\n- self.assertEqual(len(tree[2][\'children\'][1][\'children\']), 0)\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[0]["children"]), 0)\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/link1")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[2]["children"]), 2)\n+ self.assertEqual(\n+ tree[2]["children"][0]["item"].getPath(), rootPath + "/folder2/file21"\n+ )\n+ self.assertEqual(\n+ tree[2]["children"][1]["item"].getPath(), rootPath + "/folder2/folder21"\n+ )\n+ self.assertEqual(len(tree[2]["children"][1]["children"]), 0)\n \n def testGetFromRootWithNodeFilterOnFolder(self):\n class Strategy(NavtreeStrategyBase):\n-\n def nodeFilter(self, node):\n- return (\'folder\' not in node[\'item\'].getId)\n- tree = buildFolderTree(self.portal, strategy=Strategy())[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ return "folder" not in node["item"].getId\n+\n+ tree = buildFolderTree(self.portal, strategy=Strategy())["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 4)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n- self.assertEqual(tree[3][\'item\'].getPath(), rootPath + \'/link1\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/link1")\n \n def testGetFromRootWithSubtreeFilter(self):\n class Strategy(NavtreeStrategyBase):\n-\n def subtreeFilter(self, node):\n- return (\'folder2\' != node[\'item\'].getId)\n- tree = buildFolderTree(self.portal, strategy=Strategy())[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ return "folder2" != node["item"].getId\n+\n+ tree = buildFolderTree(self.portal, strategy=Strategy())["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 6)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n- self.assertEqual(tree[3][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[3][\'children\']), 3)\n- self.assertEqual(tree[3][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[3][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder1/doc12\')\n- self.assertEqual(tree[3][\'children\'][2][\n- \'item\'].getPath(), rootPath + \'/folder1/doc13\')\n- self.assertEqual(tree[4][\'item\'].getPath(), rootPath + \'/link1\')\n- self.assertEqual(tree[5][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[5][\'children\']), 0)\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[3]["children"]), 3)\n+ self.assertEqual(\n+ tree[3]["children"][0]["item"].getPath(), rootPath + "/folder1/doc11"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][1]["item"].getPath(), rootPath + "/folder1/doc12"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][2]["item"].getPath(), rootPath + "/folder1/doc13"\n+ )\n+ self.assertEqual(tree[4]["item"].getPath(), rootPath + "/link1")\n+ self.assertEqual(tree[5]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[5]["children"]), 0)\n \n def testNonFolderishObjectNotExpanded(self):\n- self.setRoles([\'Manager\'])\n- f = DummyNonStructuralFolder(\'ns_folder\')\n- self.portal._setObject(\'ns_folder\', f)\n+ self.setRoles(["Manager"])\n+ f = DummyNonStructuralFolder("ns_folder")\n+ self.portal._setObject("ns_folder", f)\n ns_folder = self.portal.ns_folder\n self.portal.portal_catalog.indexObject(self.portal.ns_folder)\n- ns_folder.invokeFactory(\'Document\', \'doc\')\n- self.setRoles([\'Member\'])\n- tree = buildFolderTree(self.portal, self.portal.ns_folder)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n- self.assertEqual(tree[-1][\'item\'].getPath(), rootPath + \'/ns_folder\')\n- self.assertEqual(len(tree[-1][\'children\']), 0)\n+ ns_folder.invokeFactory("Document", "doc")\n+ self.setRoles(["Member"])\n+ tree = buildFolderTree(self.portal, self.portal.ns_folder)["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n+ self.assertEqual(tree[-1]["item"].getPath(), rootPath + "/ns_folder")\n+ self.assertEqual(len(tree[-1]["children"]), 0)\n \n def testShowAllParentsOverridesNonFolderishObjectNotExpanded(self):\n strategy = NavtreeStrategyBase()\n strategy.showAllParents = True\n- self.setRoles([\'Manager\'])\n- f = DummyNonStructuralFolder(\'ns_folder\')\n- self.portal._setObject(\'ns_folder\', f)\n+ self.setRoles(["Manager"])\n+ f = DummyNonStructuralFolder("ns_folder")\n+ self.portal._setObject("ns_folder", f)\n ns_folder = self.portal.ns_folder\n self.portal.portal_catalog.indexObject(self.portal.ns_folder)\n- ns_folder.invokeFactory(\'Document\', \'doc\')\n- self.setRoles([\'Member\'])\n- tree = buildFolderTree(self.portal, self.portal.ns_folder.doc,\n- strategy=strategy)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n- self.assertEqual(tree[-1][\'item\'].getPath(), rootPath + \'/ns_folder\')\n- self.assertEqual(len(tree[-1][\'children\']), 1)\n- self.assertEqual(tree[-1][\'children\'][0]\n- [\'item\'].getPath(), rootPath + \'/ns_folder/doc\')\n+ ns_folder.invokeFactory("Document", "doc")\n+ self.setRoles(["Member"])\n+ tree = buildFolderTree(\n+ self.portal, self.portal.ns_folder.doc, strategy=strategy\n+ )["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n+ self.assertEqual(tree[-1]["item"].getPath(), rootPath + "/ns_folder")\n+ self.assertEqual(len(tree[-1]["children"]), 1)\n+ self.assertEqual(\n+ tree[-1]["children"][0]["item"].getPath(), rootPath + "/ns_folder/doc"\n+ )\n \n def testGetWithRootContext(self):\n- tree = buildFolderTree(self.portal, obj=self.portal)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(self.portal, obj=self.portal)["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 6)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n- self.assertEqual(tree[3][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[3][\'children\']), 3)\n- self.assertEqual(tree[3][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[3][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder1/doc12\')\n- self.assertEqual(tree[3][\'children\'][2][\n- \'item\'].getPath(), rootPath + \'/folder1/doc13\')\n- self.assertEqual(tree[4][\'item\'].getPath(), rootPath + \'/link1\')\n- self.assertEqual(tree[5][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[5][\'children\']), 5)\n- self.assertEqual(tree[5][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/doc21\')\n- self.assertEqual(tree[5][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder2/doc22\')\n- self.assertEqual(tree[5][\'children\'][2][\n- \'item\'].getPath(), rootPath + \'/folder2/doc23\')\n- self.assertEqual(tree[5][\'children\'][3][\n- \'item\'].getPath(), rootPath + \'/folder2/file21\')\n- self.assertEqual(tree[5][\'children\'][4][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21\')\n- self.assertEqual(len(tree[5][\'children\'][4][\'children\']), 2)\n- self.assertEqual(tree[5][\'children\'][4][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21/doc211\')\n- self.assertEqual(tree[5][\'children\'][4][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21/doc212\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[3]["children"]), 3)\n+ self.assertEqual(\n+ tree[3]["children"][0]["item"].getPath(), rootPath + "/folder1/doc11"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][1]["item"].getPath(), rootPath + "/folder1/doc12"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][2]["item"].getPath(), rootPath + "/folder1/doc13"\n+ )\n+ self.assertEqual(tree[4]["item"].getPath(), rootPath + "/link1")\n+ self.assertEqual(tree[5]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[5]["children"]), 5)\n+ self.assertEqual(\n+ tree[5]["children"][0]["item"].getPath(), rootPath + "/folder2/doc21"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][1]["item"].getPath(), rootPath + "/folder2/doc22"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][2]["item"].getPath(), rootPath + "/folder2/doc23"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][3]["item"].getPath(), rootPath + "/folder2/file21"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][4]["item"].getPath(), rootPath + "/folder2/folder21"\n+ )\n+ self.assertEqual(len(tree[5]["children"][4]["children"]), 2)\n+ self.assertEqual(\n+ tree[5]["children"][4]["children"][0]["item"].getPath(),\n+ rootPath + "/folder2/folder21/doc211",\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][4]["children"][1]["item"].getPath(),\n+ rootPath + "/folder2/folder21/doc212",\n+ )\n \n def testGetFromFixed(self):\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n- query = {\'path\': rootPath + \'/folder1\'}\n- tree = buildFolderTree(self.portal, query=query)[\'children\']\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n+ query = {"path": rootPath + "/folder1"}\n+ tree = buildFolderTree(self.portal, query=query)["children"]\n self.assertEqual(len(tree), 3)\n- self.assertEqual(tree[0][\'item\'].getPath(),\n- rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[1][\'item\'].getPath(),\n- rootPath + \'/folder1/doc12\')\n- self.assertEqual(tree[2][\'item\'].getPath(),\n- rootPath + \'/folder1/doc13\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder1/doc11")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/folder1/doc12")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/folder1/doc13")\n \n def testGetFromFixedAndDepth(self):\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n- query = {\'path\': rootPath + \'/folder2\', \'depth\': 1}\n- tree = buildFolderTree(self.portal, query=query)[\'children\']\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n+ query = {"path": rootPath + "/folder2", "depth": 1}\n+ tree = buildFolderTree(self.portal, query=query)["children"]\n self.assertEqual(len(tree), 5)\n- self.assertEqual(tree[0][\'item\'].getPath(),\n- rootPath + \'/folder2/doc21\')\n- self.assertEqual(tree[1][\'item\'].getPath(),\n- rootPath + \'/folder2/doc22\')\n- self.assertEqual(tree[2][\'item\'].getPath(),\n- rootPath + \'/folder2/doc23\')\n- self.assertEqual(tree[3][\'item\'].getPath(),\n- rootPath + \'/folder2/file21\')\n- self.assertEqual(tree[4][\'item\'].getPath(),\n- rootPath + \'/folder2/folder21\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder2/doc21")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/folder2/doc22")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/folder2/doc23")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/folder2/file21")\n+ self.assertEqual(tree[4]["item"].getPath(), rootPath + "/folder2/folder21")\n \n def testGetFromRootWithCurrent(self):\n context = self.portal.folder2.doc21\n- tree = buildFolderTree(self.portal, obj=context)[\'children\']\n+ tree = buildFolderTree(self.portal, obj=context)["children"]\n self.assertEqual(len(tree), 6)\n for t in tree:\n- if t[\'item\'].getId == \'folder2\':\n- self.assertEqual(t[\'currentItem\'], False)\n- self.assertEqual(t[\'currentParent\'], True)\n- for c in t[\'children\']:\n- if c[\'item\'].getId == \'doc21\':\n- self.assertEqual(c[\'currentItem\'], True)\n- self.assertEqual(c[\'currentParent\'], False)\n+ if t["item"].getId == "folder2":\n+ self.assertEqual(t["currentItem"], False)\n+ self.assertEqual(t["currentParent"], True)\n+ for c in t["children"]:\n+ if c["item"].getId == "doc21":\n+ self.assertEqual(c["currentItem"], True)\n+ self.assertEqual(c["currentParent"], False)\n else:\n- self.assertEqual(c[\'currentItem\'], False)\n- self.assertEqual(c[\'currentParent\'], False)\n+ self.assertEqual(c["currentItem"], False)\n+ self.assertEqual(c["currentParent"], False)\n else:\n- self.assertEqual(t[\'currentItem\'], False)\n- self.assertEqual(t[\'currentParent\'], False)\n+ self.assertEqual(t["currentItem"], False)\n+ self.assertEqual(t["currentParent"], False)\n \n def testGetFromRootIgnoresDefaultPages(self):\n- self.portal.folder1.setDefaultPage(\'doc12\')\n- self.portal.folder2.setDefaultPage(\'doc21\')\n- tree = buildFolderTree(self.portal)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ self.portal.folder1.setDefaultPage("doc12")\n+ self.portal.folder2.setDefaultPage("doc21")\n+ tree = buildFolderTree(self.portal)["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 6)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n- self.assertEqual(tree[3][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[3][\'children\']), 2)\n- self.assertEqual(tree[3][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[3][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder1/doc13\')\n- self.assertEqual(tree[4][\'item\'].getPath(), rootPath + \'/link1\')\n- self.assertEqual(tree[5][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[5][\'children\']), 4)\n- self.assertEqual(tree[5][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/doc22\')\n- self.assertEqual(tree[5][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder2/doc23\')\n- self.assertEqual(tree[5][\'children\'][2][\n- \'item\'].getPath(), rootPath + \'/folder2/file21\')\n- self.assertEqual(tree[5][\'children\'][3][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21\')\n- self.assertEqual(len(tree[5][\'children\'][3][\'children\']), 2)\n- self.assertEqual(tree[5][\'children\'][3][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21/doc211\')\n- self.assertEqual(tree[5][\'children\'][3][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21/doc212\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[3]["children"]), 2)\n+ self.assertEqual(\n+ tree[3]["children"][0]["item"].getPath(), rootPath + "/folder1/doc11"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][1]["item"].getPath(), rootPath + "/folder1/doc13"\n+ )\n+ self.assertEqual(tree[4]["item"].getPath(), rootPath + "/link1")\n+ self.assertEqual(tree[5]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[5]["children"]), 4)\n+ self.assertEqual(\n+ tree[5]["children"][0]["item"].getPath(), rootPath + "/folder2/doc22"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][1]["item"].getPath(), rootPath + "/folder2/doc23"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][2]["item"].getPath(), rootPath + "/folder2/file21"\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][3]["item"].getPath(), rootPath + "/folder2/folder21"\n+ )\n+ self.assertEqual(len(tree[5]["children"][3]["children"]), 2)\n+ self.assertEqual(\n+ tree[5]["children"][3]["children"][0]["item"].getPath(),\n+ rootPath + "/folder2/folder21/doc211",\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][3]["children"][1]["item"].getPath(),\n+ rootPath + "/folder2/folder21/doc212",\n+ )\n \n def testGetFromRootWithCurrentIsDefaultPage(self):\n- self.portal.folder2.setDefaultPage(\'doc21\')\n+ self.portal.folder2.setDefaultPage("doc21")\n context = self.portal.folder2.doc21\n- tree = buildFolderTree(self.portal, obj=context)[\'children\']\n+ tree = buildFolderTree(self.portal, obj=context)["children"]\n for t in tree:\n- if t[\'item\'].getId == \'folder2\':\n- self.assertEqual(t[\'currentItem\'], True)\n- self.assertEqual(t[\'currentParent\'], False)\n- for c in t[\'children\']:\n- self.assertEqual(c[\'currentItem\'], False)\n- self.assertEqual(c[\'currentParent\'], False)\n+ if t["item"].getId == "folder2":\n+ self.assertEqual(t["currentItem"], True)\n+ self.assertEqual(t["currentParent"], False)\n+ for c in t["children"]:\n+ self.assertEqual(c["currentItem"], False)\n+ self.assertEqual(c["currentParent"], False)\n else:\n- self.assertEqual(t[\'currentItem\'], False)\n- self.assertEqual(t[\'currentParent\'], False)\n+ self.assertEqual(t["currentItem"], False)\n+ self.assertEqual(t["currentParent"], False)\n \n def testGetFromRootWithCustomQuery(self):\n- query = {\'portal_type\': \'Document\'}\n- tree = buildFolderTree(self.portal, query=query)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ query = {"portal_type": "Document"}\n+ tree = buildFolderTree(self.portal, query=query)["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 3)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n \n def testGetFromRootWithDecoratorFactory(self):\n class Strategy(NavtreeStrategyBase):\n-\n def decoratorFactory(self, node):\n- node[\'foo\'] = True\n+ node["foo"] = True\n return node\n- tree = buildFolderTree(self.portal, strategy=Strategy())[\'children\']\n- self.assertEqual(tree[0][\'foo\'], True)\n+\n+ tree = buildFolderTree(self.portal, strategy=Strategy())["children"]\n+ self.assertEqual(tree[0]["foo"], True)\n \n def testShowAllParents(self):\n strategy = NavtreeStrategyBase()\n strategy.showAllParents = True\n- query = {\'portal_type\': \'Folder\'}\n+ query = {"portal_type": "Folder"}\n context = self.portal.folder1.doc11\n- tree = buildFolderTree(self.portal, query=query, obj=context,\n- strategy=strategy)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(\n+ self.portal, query=query, obj=context, strategy=strategy\n+ )["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 2)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[0][\'children\']), 1)\n- self.assertEqual(tree[0][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[1][\'children\']), 1)\n- self.assertEqual(tree[1][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[0]["children"]), 1)\n+ self.assertEqual(\n+ tree[0]["children"][0]["item"].getPath(), rootPath + "/folder1/doc11"\n+ )\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[1]["children"]), 1)\n+ self.assertEqual(\n+ tree[1]["children"][0]["item"].getPath(), rootPath + "/folder2/folder21"\n+ )\n \n def testShowAllParentsWithRestrictedParent(self):\n strategy = NavtreeStrategyBase()\n strategy.showAllParents = True\n- wftool = getToolByName(self.portal, \'portal_workflow\')\n- wftool.doActionFor(self.portal.folder1, \'hide\')\n+ wftool = getToolByName(self.portal, "portal_workflow")\n+ wftool.doActionFor(self.portal.folder1, "hide")\n self.portal.folder1.reindexObject()\n- query = {\'portal_type\': \'Folder\'}\n+ query = {"portal_type": "Folder"}\n context = self.portal.folder1.doc11\n- tree = buildFolderTree(self.portal, query=query, obj=context,\n- strategy=strategy)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(\n+ self.portal, query=query, obj=context, strategy=strategy\n+ )["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 2)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[0][\'children\']), 1)\n- self.assertEqual(tree[0][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[1][\'children\']), 1)\n- self.assertEqual(tree[1][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[0]["children"]), 1)\n+ self.assertEqual(\n+ tree[0]["children"][0]["item"].getPath(), rootPath + "/folder1/doc11"\n+ )\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[1]["children"]), 1)\n+ self.assertEqual(\n+ tree[1]["children"][0]["item"].getPath(), rootPath + "/folder2/folder21"\n+ )\n \n def testShowAllParentsWithParentNotInCatalog(self):\n strategy = NavtreeStrategyBase()\n strategy.showAllParents = True\n self.portal.folder1.unindexObject()\n- query = {\'portal_type\': \'Folder\'}\n+ query = {"portal_type": "Folder"}\n context = self.portal.folder1.doc11\n- tree = buildFolderTree(self.portal, query=query, obj=context,\n- strategy=strategy)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(\n+ self.portal, query=query, obj=context, strategy=strategy\n+ )["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n # XXX: Ideally, this shouldn\'t happen, we should get a dummy node, but\n # there\'s no way to do that with the catalog\n self.assertEqual(len(tree), 1)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/folder2\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder2")\n \n def testDontShowAllParents(self):\n strategy = NavtreeStrategyBase()\n strategy.showAllParents = False\n- query = {\'portal_type\': \'Folder\'}\n+ query = {"portal_type": "Folder"}\n context = self.portal.folder1.doc11\n- tree = buildFolderTree(self.portal, query=query, obj=context,\n- strategy=strategy)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(\n+ self.portal, query=query, obj=context, strategy=strategy\n+ )["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 2)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[0][\'children\']), 0)\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[1][\'children\']), 1)\n- self.assertEqual(tree[1][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[0]["children"]), 0)\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[1]["children"]), 1)\n+ self.assertEqual(\n+ tree[1]["children"][0]["item"].getPath(), rootPath + "/folder2/folder21"\n+ )\n \n def testGetFromRootWithCurrentNavtree(self):\n context = self.portal.folder1.doc11\n- query = {\'path\': {\'query\': \'/\'.join(context.getPhysicalPath()),\n- \'navtree\': 1}}\n- tree = buildFolderTree(self.portal, query=query)[\'children\']\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n+ query = {"path": {"query": "/".join(context.getPhysicalPath()), "navtree": 1}}\n+ tree = buildFolderTree(self.portal, query=query)["children"]\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n self.assertEqual(len(tree), 6)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n- self.assertEqual(tree[3][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[3][\'children\']), 3)\n- self.assertEqual(tree[3][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[3][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder1/doc12\')\n- self.assertEqual(tree[3][\'children\'][2][\n- \'item\'].getPath(), rootPath + \'/folder1/doc13\')\n- self.assertEqual(tree[4][\'item\'].getPath(), rootPath + \'/link1\')\n- self.assertEqual(tree[5][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[5][\'children\']), 0)\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[3]["children"]), 3)\n+ self.assertEqual(\n+ tree[3]["children"][0]["item"].getPath(), rootPath + "/folder1/doc11"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][1]["item"].getPath(), rootPath + "/folder1/doc12"\n+ )\n+ self.assertEqual(\n+ tree[3]["children"][2]["item"].getPath(), rootPath + "/folder1/doc13"\n+ )\n+ self.assertEqual(tree[4]["item"].getPath(), rootPath + "/link1")\n+ self.assertEqual(tree[5]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[5]["children"]), 0)\n \n def testGetFromRootWithCurrentNavtreeAndStartLevel(self):\n context = self.portal.folder1.doc11\n- query = {\'path\': {\'query\': \'/\'.join(context.getPhysicalPath()),\n- \'navtree\': 1,\n- \'navtree_start\': 2}}\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n- tree = buildFolderTree(self.portal, query=query)[\'children\']\n+ query = {\n+ "path": {\n+ "query": "/".join(context.getPhysicalPath()),\n+ "navtree": 1,\n+ "navtree_start": 2,\n+ }\n+ }\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(self.portal, query=query)["children"]\n self.assertEqual(len(tree), 3)\n- self.assertEqual(tree[0][\'item\'].getPath(),\n- rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[1][\'item\'].getPath(),\n- rootPath + \'/folder1/doc12\')\n- self.assertEqual(tree[2][\'item\'].getPath(),\n- rootPath + \'/folder1/doc13\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/folder1/doc11")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/folder1/doc12")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/folder1/doc13")\n \n def testGetFromRootWithCurrentNavtreePruned(self):\n context = self.portal.folder1.doc11\n \n class Strategy(NavtreeStrategyBase):\n-\n def subtreeFilter(self, node):\n- return (node[\'item\'].getId != \'folder1\')\n+ return node["item"].getId != "folder1"\n+\n showAllParents = True\n \n- query = {\'path\': {\'query\': \'/\'.join(context.getPhysicalPath()),\n- \'navtree\': 1}}\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n- tree = buildFolderTree(self.portal, query=query,\n- obj=context, strategy=Strategy())[\'children\']\n+ query = {"path": {"query": "/".join(context.getPhysicalPath()), "navtree": 1}}\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(\n+ self.portal, query=query, obj=context, strategy=Strategy()\n+ )["children"]\n self.assertEqual(len(tree), 6)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n- self.assertEqual(tree[3][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[3][\'children\']), 1)\n- self.assertEqual(tree[3][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder1/doc11\')\n- self.assertEqual(tree[4][\'item\'].getPath(), rootPath + \'/link1\')\n- self.assertEqual(tree[5][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[5][\'children\']), 0)\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[3]["children"]), 1)\n+ self.assertEqual(\n+ tree[3]["children"][0]["item"].getPath(), rootPath + "/folder1/doc11"\n+ )\n+ self.assertEqual(tree[4]["item"].getPath(), rootPath + "/link1")\n+ self.assertEqual(tree[5]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[5]["children"]), 0)\n \n def testGetFromRootWithCurrentFolderishNavtreePruned(self):\n context = self.portal.folder2.folder21\n \n class Strategy(NavtreeStrategyBase):\n-\n def subtreeFilter(self, node):\n- return (node[\'item\'].getId != \'folder2\')\n+ return node["item"].getId != "folder2"\n+\n showAllParents = True\n \n- query = {\'path\': {\'query\': \'/\'.join(context.getPhysicalPath()),\n- \'navtree\': 1}}\n- rootPath = \'/\'.join(self.portal.getPhysicalPath())\n- tree = buildFolderTree(self.portal, query=query,\n- obj=context, strategy=Strategy())[\'children\']\n+ query = {"path": {"query": "/".join(context.getPhysicalPath()), "navtree": 1}}\n+ rootPath = "/".join(self.portal.getPhysicalPath())\n+ tree = buildFolderTree(\n+ self.portal, query=query, obj=context, strategy=Strategy()\n+ )["children"]\n self.assertEqual(len(tree), 6)\n- self.assertEqual(tree[0][\'item\'].getPath(), rootPath + \'/doc1\')\n- self.assertEqual(tree[1][\'item\'].getPath(), rootPath + \'/doc2\')\n- self.assertEqual(tree[2][\'item\'].getPath(), rootPath + \'/doc3\')\n- self.assertEqual(tree[3][\'item\'].getPath(), rootPath + \'/folder1\')\n- self.assertEqual(len(tree[3][\'children\']), 0)\n- self.assertEqual(tree[4][\'item\'].getPath(), rootPath + \'/link1\')\n- self.assertEqual(tree[5][\'item\'].getPath(), rootPath + \'/folder2\')\n- self.assertEqual(len(tree[5][\'children\']), 1)\n- self.assertEqual(tree[5][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21\')\n- self.assertEqual(len(tree[5][\'children\'][0][\'children\']), 2)\n- self.assertEqual(tree[5][\'children\'][0][\'children\'][0][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21/doc211\')\n- self.assertEqual(tree[5][\'children\'][0][\'children\'][1][\n- \'item\'].getPath(), rootPath + \'/folder2/folder21/doc212\')\n+ self.assertEqual(tree[0]["item"].getPath(), rootPath + "/doc1")\n+ self.assertEqual(tree[1]["item"].getPath(), rootPath + "/doc2")\n+ self.assertEqual(tree[2]["item"].getPath(), rootPath + "/doc3")\n+ self.assertEqual(tree[3]["item"].getPath(), rootPath + "/folder1")\n+ self.assertEqual(len(tree[3]["children"]), 0)\n+ self.assertEqual(tree[4]["item"].getPath(), rootPath + "/link1")\n+ self.assertEqual(tree[5]["item"].getPath(), rootPath + "/folder2")\n+ self.assertEqual(len(tree[5]["children"]), 1)\n+ self.assertEqual(\n+ tree[5]["children"][0]["item"].getPath(), rootPath + "/folder2/folder21"\n+ )\n+ self.assertEqual(len(tree[5]["children"][0]["children"]), 2)\n+ self.assertEqual(\n+ tree[5]["children"][0]["children"][0]["item"].getPath(),\n+ rootPath + "/folder2/folder21/doc211",\n+ )\n+ self.assertEqual(\n+ tree[5]["children"][0]["children"][1]["item"].getPath(),\n+ rootPath + "/folder2/folder21/doc212",\n+ )\n \n def testCurrentParent(self):\n self.loginAsPortalOwner()\n- self.portal.invokeFactory(\'Document\', \'doc\')\n+ self.portal.invokeFactory("Document", "doc")\n context = self.portal.doc1\n- tree = buildFolderTree(self.portal, obj=context)[\'children\']\n+ tree = buildFolderTree(self.portal, obj=context)["children"]\n for t in tree:\n- if t[\'item\'].getId == \'doc\':\n- self.assertEqual(t[\'currentParent\'], False)\n+ if t["item"].getId == "doc":\n+ self.assertEqual(t["currentParent"], False)\n \n \n class TestNavigationRoot(PloneTestCase.PloneTestCase):\n-\n def testGetNavigationRootPropertyNotSet(self):\n del self.portal.portal_registry.records["plone.root"]\n root = getNavigationRoot(self.portal)\n- self.assertEqual(root, \'/\'.join(self.portal.getPhysicalPath()))\n+ self.assertEqual(root, "/".join(self.portal.getPhysicalPath()))\n \n def testGetNavigationRootPropertyEmptyNoVirtualHost(self):\n- self.portal.portal_registry[\'plone.root\'] = \'\'\n+ self.portal.portal_registry["plone.root"] = ""\n root = getNavigationRoot(self.portal)\n- self.assertEqual(root, \'/\'.join(self.portal.getPhysicalPath()))\n+ self.assertEqual(root, "/".join(self.portal.getPhysicalPath()))\n \n def testGetNavigationRootPropertyIsRoot(self):\n- self.portal.portal_registry[\'plone.root\'] = \'/\'\n+ self.portal.portal_registry["plone.root"] = "/"\n root = getNavigationRoot(self.portal)\n- self.assertEqual(root, \'/\'.join(self.portal.getPhysicalPath()))\n+ self.assertEqual(root, "/".join(self.portal.getPhysicalPath()))\n \n def testGetNavigationRootPropertyIsFolder(self):\n- folderPath = \'/\'.join(self.folder.getPhysicalPath())\n- portalPath = \'/\'.join(self.portal.getPhysicalPath())\n- relativePath = folderPath[len(portalPath):]\n- self.portal.portal_registry[\'plone.root\'] = relativePath\n+ folderPath = "/".join(self.folder.getPhysicalPath())\n+ portalPath = "/".join(self.portal.getPhysicalPath())\n+ relativePath = folderPath[len(portalPath) :]\n+ self.portal.portal_registry["plone.root"] = relativePath\n root = getNavigationRoot(self.portal)\n self.assertEqual(root, folderPath)\n \n def testGetNavigationRootWithINavigationRoot(self):\n- folderPath = \'/\'.join(self.folder.getPhysicalPath())\n- self.folder.invokeFactory(\'Folder\', \'folder1\')\n- self.folder.folder1.invokeFactory(\'Document\', \'doc1\')\n+ folderPath = "/".join(self.folder.getPhysicalPath())\n+ self.folder.invokeFactory("Folder", "folder1")\n+ self.folder.folder1.invokeFactory("Document", "doc1")\n directlyProvides(self.folder, INavigationRoot)\n root = getNavigationRoot(self.folder.folder1.doc1)\n self.assertEqual(root, folderPath)\ndiff --git a/Products/CMFPlone/tests/testNavigationView.py b/Products/CMFPlone/tests/testNavigationView.py\nindex 77500d052a..fa8d525a6b 100644\n--- a/Products/CMFPlone/tests/testNavigationView.py\n+++ b/Products/CMFPlone/tests/testNavigationView.py\n@@ -18,7 +18,7 @@\n \n class TestSiteMap(PloneTestCase.PloneTestCase):\n """Tests for the sitemap view implementations. This base test is a little\n- geared toward a catalog based implementation for now.\n+ geared toward a catalog based implementation for now.\n """\n \n view_class = CatalogSiteMap\n@@ -29,30 +29,29 @@ def afterSetUp(self):\n self.populateSite()\n registry = getUtility(IRegistry)\n self.navigation_settings = registry.forInterface(\n- INavigationSchema,\n- prefix=\'plone\'\n+ INavigationSchema, prefix="plone"\n )\n \n def populateSite(self):\n- self.setRoles([\'Manager\'])\n- self.portal.invokeFactory(\'Document\', \'doc1\')\n- self.portal.invokeFactory(\'Document\', \'doc2\')\n- self.portal.invokeFactory(\'Document\', \'doc3\')\n- self.portal.invokeFactory(\'Folder\', \'folder1\')\n- self.portal.invokeFactory(\'Link\', \'link1\')\n- self.portal.link1.remoteUrl = \'http://plone.org\'\n+ self.setRoles(["Manager"])\n+ self.portal.invokeFactory("Document", "doc1")\n+ self.portal.invokeFactory("Document", "doc2")\n+ self.portal.invokeFactory("Document", "doc3")\n+ self.portal.invokeFactory("Folder", "folder1")\n+ self.portal.invokeFactory("Link", "link1")\n+ self.portal.link1.remoteUrl = "http://plone.org"\n self.portal.link1.reindexObject()\n- folder1 = getattr(self.portal, \'folder1\')\n- folder1.invokeFactory(\'Document\', \'doc11\')\n- folder1.invokeFactory(\'Document\', \'doc12\')\n- folder1.invokeFactory(\'Document\', \'doc13\')\n- self.portal.invokeFactory(\'Folder\', \'folder2\')\n- folder2 = getattr(self.portal, \'folder2\')\n- folder2.invokeFactory(\'Document\', \'doc21\')\n- folder2.invokeFactory(\'Document\', \'doc22\')\n- folder2.invokeFactory(\'Document\', \'doc23\')\n- folder2.invokeFactory(\'File\', \'file21\')\n- self.setRoles([\'Member\'])\n+ folder1 = getattr(self.portal, "folder1")\n+ folder1.invokeFactory("Document", "doc11")\n+ folder1.invokeFactory("Document", "doc12")\n+ folder1.invokeFactory("Document", "doc13")\n+ self.portal.invokeFactory("Folder", "folder2")\n+ folder2 = getattr(self.portal, "folder2")\n+ folder2.invokeFactory("Document", "doc21")\n+ folder2.invokeFactory("Document", "doc22")\n+ folder2.invokeFactory("Document", "doc23")\n+ folder2.invokeFactory("File", "file21")\n+ self.setRoles(["Member"])\n \n def testCreateSitemap(self):\n view = self.view_class(self.portal, self.request)\n@@ -62,64 +61,65 @@ def testCreateSitemap(self):\n def testComplexSitemap(self):\n # create and test a reasonabley complex sitemap\n def path(x):\n- return \'/\'.join(x.getPhysicalPath())\n+ return "/".join(x.getPhysicalPath())\n+\n # We do this in a strange order in order to maximally demonstrate the\n # bug\n folder1 = self.portal.folder1\n- folder1.invokeFactory(\'Folder\', \'subfolder1\')\n+ folder1.invokeFactory("Folder", "subfolder1")\n subfolder1 = folder1.subfolder1\n- folder1.invokeFactory(\'Folder\', \'subfolder2\')\n+ folder1.invokeFactory("Folder", "subfolder2")\n subfolder2 = folder1.subfolder2\n- subfolder1.invokeFactory(\'Folder\', \'subfolder11\')\n+ subfolder1.invokeFactory("Folder", "subfolder11")\n subfolder11 = subfolder1.subfolder11\n- subfolder1.invokeFactory(\'Folder\', \'subfolder12\')\n- subfolder2.invokeFactory(\'Folder\', \'subfolder21\')\n+ subfolder1.invokeFactory("Folder", "subfolder12")\n+ subfolder2.invokeFactory("Folder", "subfolder21")\n subfolder21 = subfolder2.subfolder21\n- folder1.invokeFactory(\'Folder\', \'subfolder3\')\n+ folder1.invokeFactory("Folder", "subfolder3")\n subfolder3 = folder1.subfolder3\n- subfolder2.invokeFactory(\'Folder\', \'subfolder22\')\n+ subfolder2.invokeFactory("Folder", "subfolder22")\n subfolder22 = subfolder2.subfolder22\n- subfolder22.invokeFactory(\'Folder\', \'subfolder221\')\n+ subfolder22.invokeFactory("Folder", "subfolder221")\n subfolder221 = subfolder22.subfolder221\n \n # Increase depth\n- self.portal.portal_registry[\'plone.sitemap_depth\'] = 5\n+ self.portal.portal_registry["plone.sitemap_depth"] = 5\n \n view = self.view_class(self.portal, self.request)\n sitemap = view.siteMap()\n \n- folder1map = sitemap[\'children\'][6]\n- self.assertEqual(len(folder1map[\'children\']), 6)\n- self.assertEqual(folder1map[\'item\'].getPath(), path(folder1))\n+ folder1map = sitemap["children"][6]\n+ self.assertEqual(len(folder1map["children"]), 6)\n+ self.assertEqual(folder1map["item"].getPath(), path(folder1))\n \n- subfolder1map = folder1map[\'children\'][3]\n- self.assertEqual(subfolder1map[\'item\'].getPath(), path(subfolder1))\n- self.assertEqual(len(subfolder1map[\'children\']), 2)\n+ subfolder1map = folder1map["children"][3]\n+ self.assertEqual(subfolder1map["item"].getPath(), path(subfolder1))\n+ self.assertEqual(len(subfolder1map["children"]), 2)\n \n- subfolder2map = folder1map[\'children\'][4]\n- self.assertEqual(subfolder2map[\'item\'].getPath(), path(subfolder2))\n- self.assertEqual(len(subfolder2map[\'children\']), 2)\n+ subfolder2map = folder1map["children"][4]\n+ self.assertEqual(subfolder2map["item"].getPath(), path(subfolder2))\n+ self.assertEqual(len(subfolder2map["children"]), 2)\n \n- subfolder3map = folder1map[\'children\'][5]\n- self.assertEqual(subfolder3map[\'item\'].getPath(), path(subfolder3))\n- self.assertEqual(len(subfolder3map[\'children\']), 0)\n+ subfolder3map = folder1map["children"][5]\n+ self.assertEqual(subfolder3map["item"].getPath(), path(subfolder3))\n+ self.assertEqual(len(subfolder3map["children"]), 0)\n \n- subfolder11map = subfolder1map[\'children\'][0]\n- self.assertEqual(subfolder11map[\'item\'].getPath(), path(subfolder11))\n- self.assertEqual(len(subfolder11map[\'children\']), 0)\n+ subfolder11map = subfolder1map["children"][0]\n+ self.assertEqual(subfolder11map["item"].getPath(), path(subfolder11))\n+ self.assertEqual(len(subfolder11map["children"]), 0)\n \n- subfolder21map = subfolder2map[\'children\'][0]\n- self.assertEqual(subfolder21map[\'item\'].getPath(), path(subfolder21))\n- self.assertEqual(len(subfolder21map[\'children\']), 0)\n+ subfolder21map = subfolder2map["children"][0]\n+ self.assertEqual(subfolder21map["item"].getPath(), path(subfolder21))\n+ self.assertEqual(len(subfolder21map["children"]), 0)\n \n- subfolder22map = subfolder2map[\'children\'][1]\n- self.assertEqual(subfolder22map[\'item\'].getPath(), path(subfolder22))\n- self.assertEqual(len(subfolder22map[\'children\']), 1)\n+ subfolder22map = subfolder2map["children"][1]\n+ self.assertEqual(subfolder22map["item"].getPath(), path(subfolder22))\n+ self.assertEqual(len(subfolder22map["children"]), 1)\n \n # Why isn\'t this showing up in the sitemap\n- subfolder221map = subfolder22map[\'children\'][0]\n- self.assertEqual(subfolder221map[\'item\'].getPath(), path(subfolder221))\n- self.assertEqual(len(subfolder221map[\'children\']), 0)\n+ subfolder221map = subfolder22map["children"][0]\n+ self.assertEqual(subfolder221map["item"].getPath(), path(subfolder221))\n+ self.assertEqual(len(subfolder221map["children"]), 0)\n \n def testSitemapUnchangedWithTopLevel(self):\n # Test that setting topLevel does not alter the sitemap\n@@ -128,8 +128,9 @@ def testSitemapUnchangedWithTopLevel(self):\n ntp.manage_changeProperties(topLevel=topLevel)\n view = self.view_class(self.portal, self.request)\n sitemap = view.siteMap()\n- self.assertEqual(sitemap[\'children\'][-1][\'item\'].getPath(),\n- \'/plone/folder2\')\n+ self.assertEqual(\n+ sitemap["children"][-1]["item"].getPath(), "/plone/folder2"\n+ )\n \n def testSitemapUnchangedWithBottomLevel(self):\n # Test that setting bottomLevel does not alter the sitemap\n@@ -138,22 +139,24 @@ def testSitemapUnchangedWithBottomLevel(self):\n ntp.manage_changeProperties(bottomLevel=bottomLevel)\n view = self.view_class(self.portal, self.request)\n sitemap = view.siteMap()\n- self.assertEqual(sitemap[\'children\'][-1][\'item\'].getPath(),\n- \'/plone/folder2\')\n- self.assertTrue(len(sitemap[\'children\'][-1][\'children\']) > 0)\n+ self.assertEqual(\n+ sitemap["children"][-1]["item"].getPath(), "/plone/folder2"\n+ )\n+ self.assertTrue(len(sitemap["children"][-1]["children"]) > 0)\n \n def testSitemapWithNavigationRoot(self):\n- self.navigation_settings.root = \'/folder2\'\n+ self.navigation_settings.root = "/folder2"\n view = self.view_class(self.portal, self.request)\n sitemap = view.siteMap()\n- self.assertEqual(sitemap[\'children\'][-1][\'item\'].getPath(),\n- \'/plone/folder2/doc23\')\n+ self.assertEqual(\n+ sitemap["children"][-1]["item"].getPath(), "/plone/folder2/doc23"\n+ )\n \n \n class TestBasePortalTabs(PloneTestCase.PloneTestCase):\n """Tests for the portal tabs view implementations\n- This base test is a little geared toward a catalog based implementation\n- for now.\n+ This base test is a little geared toward a catalog based implementation\n+ for now.\n """\n \n view_class = None\n@@ -165,19 +168,16 @@ def afterSetUp(self):\n @property\n def navigation_settings(self):\n registry = getUtility(IRegistry)\n- return registry.forInterface(\n- INavigationSchema,\n- prefix=\'plone\'\n- )\n+ return registry.forInterface(INavigationSchema, prefix="plone")\n \n def populateSite(self):\n- self.setRoles([\'Manager\'])\n- self.portal.invokeFactory(\'Document\', \'doc1\')\n- self.portal.invokeFactory(\'Document\', \'doc2\')\n- self.portal.invokeFactory(\'Document\', \'doc3\')\n- self.portal.invokeFactory(\'Folder\', \'folder1\')\n- self.portal.invokeFactory(\'Folder\', \'folder2\')\n- self.setRoles([\'Member\'])\n+ self.setRoles(["Manager"])\n+ self.portal.invokeFactory("Document", "doc1")\n+ self.portal.invokeFactory("Document", "doc2")\n+ self.portal.invokeFactory("Document", "doc3")\n+ self.portal.invokeFactory("Folder", "folder1")\n+ self.portal.invokeFactory("Folder", "folder2")\n+ self.setRoles(["Member"])\n \n def testCreateTopLevelTabs(self):\n # See if we can create one at all\n@@ -198,8 +198,8 @@ def testTabsRespectFolderOrder(self):\n view = self.view_class(self.portal, self.request)\n tabs1 = view.topLevelTabs(actions=[])\n # Must be manager to change order on portal itself\n- self.setRoles([\'Manager\', \'Member\'])\n- folder_position(self.portal, \'up\', \'folder2\')\n+ self.setRoles(["Manager", "Member"])\n+ folder_position(self.portal, "up", "folder2")\n view = self.view_class(self.portal, self.request)\n tabs2 = view.topLevelTabs(actions=[])\n # Same number of objects\n@@ -210,22 +210,21 @@ def testTabsRespectFolderOrder(self):\n def testCustomQuery(self):\n # Try a custom query script for the tabs that returns only published\n # objects\n- self.portal._delObject(\'Members\')\n- self.portal._delObject(\'news\')\n- self.portal._delObject(\'events\')\n+ self.portal._delObject("Members")\n+ self.portal._delObject("news")\n+ self.portal._delObject("events")\n workflow = self.portal.portal_workflow\n- factory = self.portal.manage_addProduct[\'PythonScripts\']\n- factory.manage_addPythonScript(\'getCustomNavQuery\')\n+ factory = self.portal.manage_addProduct["PythonScripts"]\n+ factory.manage_addPythonScript("getCustomNavQuery")\n script = self.portal.getCustomNavQuery\n- script.ZPythonScript_edit(\'\', \'return {"review_state":"published"}\')\n- self.assertEqual(\n- self.portal.getCustomNavQuery(), {"review_state": "published"})\n+ script.ZPythonScript_edit("", \'return {"review_state":"published"}\')\n+ self.assertEqual(self.portal.getCustomNavQuery(), {"review_state": "published"})\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n # Should contain no folders\n self.assertEqual(len(tabs), 0)\n # change workflow for folder1\n- workflow.doActionFor(self.portal.folder1, \'publish\')\n+ workflow.doActionFor(self.portal.folder1, "publish")\n self.portal.folder1.reindexObject()\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n@@ -234,19 +233,19 @@ def testCustomQuery(self):\n \n def testStateFiltering(self):\n # Test tabs workflow state filtering\n- self.portal._delObject(\'Members\')\n- self.portal._delObject(\'news\')\n- self.portal._delObject(\'events\')\n+ self.portal._delObject("Members")\n+ self.portal._delObject("news")\n+ self.portal._delObject("events")\n workflow = self.portal.portal_workflow\n \n- self.navigation_settings.workflow_states_to_show = (\'published\',)\n+ self.navigation_settings.workflow_states_to_show = ("published",)\n self.navigation_settings.filter_on_workflow = True\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n # Should contain no folders\n self.assertEqual(len(tabs), 0)\n # change workflow for folder1\n- workflow.doActionFor(self.portal.folder1, \'publish\')\n+ workflow.doActionFor(self.portal.folder1, "publish")\n self.portal.folder1.reindexObject()\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n@@ -254,9 +253,9 @@ def testStateFiltering(self):\n self.assertEqual(len(tabs), 1)\n \n def testTabInfo(self):\n- self.portal._delObject(\'Members\')\n- self.portal._delObject(\'news\')\n- self.portal._delObject(\'events\')\n+ self.portal._delObject("Members")\n+ self.portal._delObject("news")\n+ self.portal._delObject("events")\n \n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n@@ -264,11 +263,11 @@ def testTabInfo(self):\n self.assertEqual(len(tabs), 5)\n \n tab = tabs[0]\n- self.assertTrue(\'url\' in tab and tab[\'url\']) # url must not be empty\n- self.assertTrue(\'description\' in tab) # our description is empty\n- self.assertTrue(\'name\' in tab and tab[\'name\'])\n- self.assertTrue(\'id\' in tab and tab[\'id\'])\n- self.assertTrue(\'review_state\' in tab and tab[\'review_state\'])\n+ self.assertTrue("url" in tab and tab["url"]) # url must not be empty\n+ self.assertTrue("description" in tab) # our description is empty\n+ self.assertTrue("name" in tab and tab["name"])\n+ self.assertTrue("id" in tab and tab["id"])\n+ self.assertTrue("review_state" in tab and tab["review_state"])\n \n def testDisableFolderTabs(self):\n # Setting the site_property disable_folder_sections should remove\n@@ -285,21 +284,21 @@ def testTabsExcludeItemsWithExcludeProperty(self):\n # if we\'re not in context of the excluded item it should disappear\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n- tab_names = [t[\'id\'] for t in tabs]\n- self.assertNotIn(\'folder2\', tab_names)\n+ tab_names = [t["id"] for t in tabs]\n+ self.assertNotIn("folder2", tab_names)\n \n # if we\'re inside, it also should stay hidden\n view = self.view_class(self.portal.folder2, self.request)\n tabs = view.topLevelTabs(actions=[])\n- tab_names = [t[\'id\'] for t in tabs]\n- self.assertNotIn(\'folder2\', tab_names)\n+ tab_names = [t["id"] for t in tabs]\n+ self.assertNotIn("folder2", tab_names)\n \n # Now we flip the setting for plone.show_excluded_items\n self.navigation_settings.show_excluded_items = True\n view = self.view_class(self.portal.folder2, self.request)\n tabs = view.topLevelTabs(actions=[])\n- tab_names = [t[\'id\'] for t in tabs]\n- self.assertIn(\'folder2\', tab_names)\n+ tab_names = [t["id"] for t in tabs]\n+ self.assertIn("folder2", tab_names)\n \n def testTabsRespectsTypesWithViewAction(self):\n # With a type in types_use_view_action_in_listings as current action it\n@@ -308,76 +307,70 @@ def testTabsRespectsTypesWithViewAction(self):\n tabs = view.topLevelTabs(actions=[])\n self.assertTrue(tabs)\n # Fail if \'view\' is used for folder\n- self.assertFalse(tabs[-1][\'url\'][-5:] == \'/view\')\n+ self.assertFalse(tabs[-1]["url"][-5:] == "/view")\n # Add Folder to type settings\n registry = getUtility(IRegistry)\n- type_settings = registry.forInterface(\n- ITypesSchema,\n- prefix="plone",\n- check=False\n- )\n- type_settings.types_use_view_action_in_listings = [\n- \'Image\', \'File\', \'Folder\'\n- ]\n+ type_settings = registry.forInterface(ITypesSchema, prefix="plone", check=False)\n+ type_settings.types_use_view_action_in_listings = ["Image", "File", "Folder"]\n # Verify that we have \'/view\'\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n self.assertTrue(tabs)\n- self.assertEqual(tabs[-1][\'url\'][-5:], \'/view\')\n+ self.assertEqual(tabs[-1]["url"][-5:], "/view")\n \n def testTabsExcludeNonFolderishItems(self):\n self.navigation_settings.nonfolderish_tabs = False\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n orig_len = len(tabs)\n- self.setRoles([\'Manager\', \'Member\'])\n- self.portal.invokeFactory(\'Document\', \'foo\')\n+ self.setRoles(["Manager", "Member"])\n+ self.portal.invokeFactory("Document", "foo")\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n self.assertTrue(tabs)\n self.assertEqual(len(tabs), orig_len)\n \n def testRootBelowPortalRoot(self):\n- self.setRoles([\'Manager\'])\n- self.portal.manage_delObjects([\'news\', \'events\', \'Members\'])\n- self.setRoles([\'Member\'])\n+ self.setRoles(["Manager"])\n+ self.portal.manage_delObjects(["news", "events", "Members"])\n+ self.setRoles(["Member"])\n self.navigation_settings.nonfolderish_tabs = False\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n self.assertTrue(tabs)\n self.assertEqual(len(tabs), 2)\n- self.assertEqual(tabs[0][\'id\'], \'folder1\')\n- self.assertEqual(tabs[1][\'id\'], \'folder2\')\n+ self.assertEqual(tabs[0]["id"], "folder1")\n+ self.assertEqual(tabs[1]["id"], "folder2")\n \n def testPortalTabsNotIncludeViewNamesInCSSid(self):\n- self.setRoles([\'Manager\'])\n- self.portal.invokeFactory(\'File\', \'file1\')\n+ self.setRoles(["Manager"])\n+ self.portal.invokeFactory("File", "file1")\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n for tab in tabs:\n- self.assertEqual(validateCSSIdentifier(tab[\'id\']), True)\n+ self.assertEqual(validateCSSIdentifier(tab["id"]), True)\n \n def testLinkRemoteUrlsUsedUnlessLinkCreator(self):\n- self.setRoles([\'Manager\'])\n- self.portal.invokeFactory(\'Link\', \'link1\')\n- self.portal.link1.remoteUrl = \'http://plone.org\'\n+ self.setRoles(["Manager"])\n+ self.portal.invokeFactory("Link", "link1")\n+ self.portal.link1.remoteUrl = "http://plone.org"\n self.portal.link1.reindexObject()\n view = self.view_class(self.portal, self.request)\n tabs = view.topLevelTabs(actions=[])\n for tab in tabs:\n # as Creator tab for link1 should have url of the item\n- if tab[\'id\'] == \'link1\':\n- self.assertTrue(tab[\'url\'] == \'http://nohost/plone/link1\')\n+ if tab["id"] == "link1":\n+ self.assertTrue(tab["url"] == "http://nohost/plone/link1")\n \n- self.setRoles([\'Manager\'])\n- self.portal.link1.setCreators([\'some_other_user\'])\n+ self.setRoles(["Manager"])\n+ self.portal.link1.setCreators(["some_other_user"])\n self.portal.link1.reindexObject()\n tabs = view.topLevelTabs(actions=[])\n for tab in tabs:\n # as non-Creator user, tab for link1 should have url of the remote\n # url\n- if tab[\'id\'] == \'link1\':\n- self.assertTrue(tab[\'url\'] == \'http://plone.org\')\n+ if tab["id"] == "link1":\n+ self.assertTrue(tab["url"] == "http://plone.org")\n \n \n class TestCatalogPortalTabs(TestBasePortalTabs):\n@@ -385,8 +378,7 @@ class TestCatalogPortalTabs(TestBasePortalTabs):\n \n \n class TestBaseBreadCrumbs(PloneTestCase.PloneTestCase):\n- """Tests for the portal tabs query\n- """\n+ """Tests for the portal tabs query"""\n \n view_class = None\n \n@@ -395,17 +387,16 @@ def afterSetUp(self):\n self.populateSite()\n registry = getUtility(IRegistry)\n self.navigation_settings = registry.forInterface(\n- INavigationSchema,\n- prefix=\'plone\'\n+ INavigationSchema, prefix="plone"\n )\n \n def populateSite(self):\n- self.setRoles([\'Manager\'])\n- self.portal.invokeFactory(\'Folder\', \'folder1\')\n- folder1 = getattr(self.portal, \'folder1\')\n- folder1.invokeFactory(\'Document\', \'doc11\')\n- folder1.invokeFactory(\'File\', \'file11\')\n- self.setRoles([\'Member\'])\n+ self.setRoles(["Manager"])\n+ self.portal.invokeFactory("Folder", "folder1")\n+ folder1 = getattr(self.portal, "folder1")\n+ folder1.invokeFactory("Document", "doc11")\n+ folder1.invokeFactory("File", "file11")\n+ self.setRoles(["Member"])\n \n def testCreateBreadCrumbs(self):\n # See if we can create one at all\n@@ -414,9 +405,8 @@ def testCreateBreadCrumbs(self):\n crumbs = view.breadcrumbs()\n self.assertTrue(crumbs)\n self.assertEqual(len(crumbs), 2)\n- self.assertEqual(crumbs[-1][\'absolute_url\'], doc.absolute_url())\n- self.assertEqual(crumbs[-2][\'absolute_url\'],\n- doc.aq_parent.absolute_url())\n+ self.assertEqual(crumbs[-1]["absolute_url"], doc.absolute_url())\n+ self.assertEqual(crumbs[-2]["absolute_url"], doc.aq_parent.absolute_url())\n \n def testBreadcrumbsRespectTypesWithViewAction(self):\n # With a type in types_use_view_action_in_listings as current action it\n@@ -424,25 +414,24 @@ def testBreadcrumbsRespectTypesWithViewAction(self):\n view = self.view_class(self.portal.folder1.file11, self.request)\n crumbs = view.breadcrumbs()\n self.assertTrue(crumbs)\n- self.assertEqual(crumbs[-1][\'absolute_url\'][-5:], \'/view\')\n+ self.assertEqual(crumbs[-1]["absolute_url"][-5:], "/view")\n \n def testBreadcrumbsStopAtNavigationRoot(self):\n self.navigation_settings.top_level = 1\n- self.navigation_settings.root = \'/folder1\'\n+ self.navigation_settings.root = "/folder1"\n view = self.view_class(self.portal.folder1.doc11, self.request)\n crumbs = view.breadcrumbs()\n self.assertTrue(crumbs)\n- self.assertEqual(crumbs[0][\'absolute_url\'],\n- self.portal.folder1.doc11.absolute_url())\n+ self.assertEqual(\n+ crumbs[0]["absolute_url"], self.portal.folder1.doc11.absolute_url()\n+ )\n \n \n class TestCatalogBreadCrumbs(TestBaseBreadCrumbs):\n-\n view_class = CatalogNavigationBreadcrumbs\n \n \n class TestPhysicalBreadCrumbs(TestBaseBreadCrumbs):\n-\n view_class = PhysicalNavigationBreadcrumbs\n \n def testBreadcrumbsFilterByInterface(self):\n@@ -451,29 +440,31 @@ def testBreadcrumbsFilterByInterface(self):\n directlyProvides(self.portal.folder1, IHideFromBreadcrumbs)\n newcrumbs = view.breadcrumbs()\n self.assertEqual(len(crumbs) - 1, len(newcrumbs))\n- self.assertEqual(newcrumbs[-1][\'absolute_url\'],\n- self.portal.folder1.doc11.absolute_url())\n+ self.assertEqual(\n+ newcrumbs[-1]["absolute_url"], self.portal.folder1.doc11.absolute_url()\n+ )\n \n def testBreadcrumbsFilterByInterface2(self):\n # Test url of subfolder of hidden folder.\n- self.portal.folder1.invokeFactory(\'Folder\', \'subfolder11\')\n+ self.portal.folder1.invokeFactory("Folder", "subfolder11")\n directlyProvides(self.portal.folder1.subfolder11, IHideFromBreadcrumbs)\n- self.portal.folder1.subfolder11.invokeFactory(\'Folder\', \'subfolder111\')\n+ self.portal.folder1.subfolder11.invokeFactory("Folder", "subfolder111")\n self.portal.folder1.subfolder11.subfolder111.invokeFactory(\n- \'Document\', \'doc1111\')\n+ "Document", "doc1111"\n+ )\n doc1111 = self.portal.folder1.subfolder11.subfolder111.doc1111\n view = self.view_class(doc1111, self.request)\n newcrumbs = view.breadcrumbs()\n self.assertEqual(\n- newcrumbs[-2][\'absolute_url\'],\n- self.portal.folder1.subfolder11.subfolder111.absolute_url()\n- )\n-\n+ newcrumbs[-2]["absolute_url"],\n+ self.portal.folder1.subfolder11.subfolder111.absolute_url(),\n+ )\n \n \n def test_suite():\n from unittest import makeSuite\n from unittest import TestSuite\n+\n suite = TestSuite()\n suite.addTest(makeSuite(TestCatalogPortalTabs))\n suite.addTest(makeSuite(TestSiteMap))\ndiff --git a/Products/CMFPlone/tests/testNextPrevious.py b/Products/CMFPlone/tests/testNextPrevious.py\nindex 06139e9f71..fdbaca7eb4 100644\n--- a/Products/CMFPlone/tests/testNextPrevious.py\n+++ b/Products/CMFPlone/tests/testNextPrevious.py\n@@ -3,39 +3,37 @@\n \n \n class TestNextPrevious(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n self.populateSite()\n \n # set up a lot of content - can be reused in each (sub)test\n def populateSite(self):\n- self.setRoles([\'Manager\'])\n- self.portal.invokeFactory(\'Document\', \'doc1\')\n- self.portal.invokeFactory(\'Document\', \'doc2\')\n- self.portal.invokeFactory(\'Document\', \'doc3\')\n- self.portal.invokeFactory(\'Folder\', \'folder1\')\n- self.portal.invokeFactory(\'Link\', \'link1\')\n- self.portal.link1.remoteUrl = \'http://plone.org\'\n+ self.setRoles(["Manager"])\n+ self.portal.invokeFactory("Document", "doc1")\n+ self.portal.invokeFactory("Document", "doc2")\n+ self.portal.invokeFactory("Document", "doc3")\n+ self.portal.invokeFactory("Folder", "folder1")\n+ self.portal.invokeFactory("Link", "link1")\n+ self.portal.link1.remoteUrl = "http://plone.org"\n self.portal.link1.reindexObject()\n- folder1 = getattr(self.portal, \'folder1\')\n- folder1.invokeFactory(\'Document\', \'doc11\')\n- folder1.invokeFactory(\'Document\', \'doc12\')\n- folder1.invokeFactory(\'Document\', \'doc13\')\n- self.portal.invokeFactory(\'Folder\', \'folder2\')\n- folder2 = getattr(self.portal, \'folder2\')\n- folder2.invokeFactory(\'Document\', \'doc21\')\n- folder2.invokeFactory(\'Document\', \'doc22\')\n- folder2.invokeFactory(\'Document\', \'doc23\')\n- folder2.invokeFactory(\'File\', \'file21\')\n- self.setRoles([\'Member\'])\n+ folder1 = getattr(self.portal, "folder1")\n+ folder1.invokeFactory("Document", "doc11")\n+ folder1.invokeFactory("Document", "doc12")\n+ folder1.invokeFactory("Document", "doc13")\n+ self.portal.invokeFactory("Folder", "folder2")\n+ folder2 = getattr(self.portal, "folder2")\n+ folder2.invokeFactory("Document", "doc21")\n+ folder2.invokeFactory("Document", "doc22")\n+ folder2.invokeFactory("Document", "doc23")\n+ folder2.invokeFactory("File", "file21")\n+ self.setRoles(["Member"])\n \n def testIfFolderImplementsPreviousNext(self):\n- self.folder.invokeFactory(\'Folder\', \'case\')\n- self.assertTrue(\n- INextPreviousProvider(self.folder.case, None) is not None)\n+ self.folder.invokeFactory("Folder", "case")\n+ self.assertTrue(INextPreviousProvider(self.folder.case, None) is not None)\n \n def testNextPreviousEnablingOnCreation(self):\n- self.folder.invokeFactory(\'Folder\', \'case\')\n+ self.folder.invokeFactory("Folder", "case")\n \n # first the field on the atfolder direct, to get sure the field is\n # there\n@@ -48,7 +46,8 @@ def testNextPreviousEnablingOnCreation(self):\n \n def testNextPreviousViewDisabled(self):\n view = self.portal.folder1.doc11.restrictedTraverse(\n- \'@@plone_nextprevious_view\', None)\n+ "@@plone_nextprevious_view", None\n+ )\n self.assertFalse(view is None)\n \n # is it enabled (default is false)\n@@ -60,33 +59,30 @@ def testNextPreviousViewEnabled(self):\n \n # clear request memos\n view = self.portal.folder1.doc12.restrictedTraverse(\n- \'@@plone_nextprevious_view\', None)\n+ "@@plone_nextprevious_view", None\n+ )\n self.assertTrue(view.enabled())\n \n # test the next method\n next = view.next()\n- self.assertEqual(next[\'url\'],\n- self.portal.folder1.doc13.absolute_url())\n+ self.assertEqual(next["url"], self.portal.folder1.doc13.absolute_url())\n \n # test the previous method\n previous = view.previous()\n- self.assertEqual(previous[\'url\'],\n- self.portal.folder1.doc11.absolute_url())\n+ self.assertEqual(previous["url"], self.portal.folder1.doc11.absolute_url())\n \n def testAdapterOnPortal(self):\n- view = self.portal.doc1.restrictedTraverse(\'@@plone_nextprevious_view\',\n- None)\n+ view = self.portal.doc1.restrictedTraverse("@@plone_nextprevious_view", None)\n self.assertTrue(view)\n self.assertFalse(view.enabled())\n self.assertEqual(None, view.next())\n self.assertEqual(None, view.previous())\n \n def testNextPreviousItems(self):\n- self.folder.invokeFactory(\'Folder\', \'case3\')\n+ self.folder.invokeFactory("Folder", "case3")\n \n for documentCounter in range(1, 6):\n- self.folder.case3.invokeFactory(\'Document\',\n- \'subDoc%d\' % documentCounter)\n+ self.folder.case3.invokeFactory("Document", "subDoc%d" % documentCounter)\n \n container = self.folder.case3\n \n@@ -95,14 +91,14 @@ def testNextPreviousItems(self):\n \n # test the next item of subDoc2\n next = adapter.getNextItem(self.folder.case3.subDoc2)\n- self.assertEqual(next["id"], \'subDoc3\')\n+ self.assertEqual(next["id"], "subDoc3")\n \n # test that the contenttype is defined correct\n- self.assertEqual(next["portal_type"], \'Document\')\n+ self.assertEqual(next["portal_type"], "Document")\n \n # test the previous item of subDoc2\n previous = adapter.getPreviousItem(self.folder.case3.subDoc2)\n- self.assertEqual(previous["id"], \'subDoc1\')\n+ self.assertEqual(previous["id"], "subDoc1")\n \n # first item should not have a previous item\n previous = adapter.getPreviousItem(self.folder.case3.subDoc1)\ndiff --git a/Products/CMFPlone/tests/testOrderSupport.py b/Products/CMFPlone/tests/testOrderSupport.py\nindex 7d5bb891a7..c0421e091f 100644\n--- a/Products/CMFPlone/tests/testOrderSupport.py\n+++ b/Products/CMFPlone/tests/testOrderSupport.py\n@@ -4,202 +4,199 @@\n \n \n class TestOrderSupport(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n # Add a bunch of subobjects we can order later on\n- self.folder.invokeFactory(\'Document\', id=\'foo\')\n- self.folder.invokeFactory(\'Document\', id=\'bar\')\n- self.folder.invokeFactory(\'Document\', id=\'baz\')\n+ self.folder.invokeFactory("Document", id="foo")\n+ self.folder.invokeFactory("Document", id="bar")\n+ self.folder.invokeFactory("Document", id="baz")\n \n def testGetObjectPosition(self):\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testMoveObject(self):\n- self.folder.moveObjectToPosition(\'foo\', 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.moveObjectToPosition("foo", 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testMoveObjectToSamePos(self):\n- self.folder.moveObjectToPosition(\'bar\', 1)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.moveObjectToPosition("bar", 1)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testMoveObjectToFirstPos(self):\n- self.folder.moveObjectToPosition(\'bar\', 0)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.moveObjectToPosition("bar", 0)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testMoveObjectToLastPos(self):\n- self.folder.moveObjectToPosition(\'bar\', 2)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.moveObjectToPosition("bar", 2)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def testMoveObjectOutLowerBounds(self):\n # Pos will be normalized to 0\n- self.folder.moveObjectToPosition(\'bar\', -1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.moveObjectToPosition("bar", -1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testMoveObjectOutUpperBounds(self):\n # Pos will be normalized to 2\n- self.folder.moveObjectToPosition(\'bar\', 3)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.moveObjectToPosition("bar", 3)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def testMoveObjectsUp(self):\n- self.folder.moveObjectsUp([\'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.moveObjectsUp(["bar"])\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testMoveObjectsDown(self):\n- self.folder.moveObjectsDown([\'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.moveObjectsDown(["bar"])\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def testMoveObjectsToTop(self):\n- self.folder.moveObjectsToTop([\'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.moveObjectsToTop(["bar"])\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testMoveObjectsToBottom(self):\n- self.folder.moveObjectsToBottom([\'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.moveObjectsToBottom(["bar"])\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def testMoveTwoObjectsUp(self):\n- self.folder.moveObjectsUp([\'bar\', \'baz\'])\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 2)\n+ self.folder.moveObjectsUp(["bar", "baz"])\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 2)\n \n def testMoveTwoObjectsDown(self):\n- self.folder.moveObjectsDown([\'foo\', \'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.moveObjectsDown(["foo", "bar"])\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def testMoveTwoObjectsToTop(self):\n- self.folder.moveObjectsToTop([\'bar\', \'baz\'])\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 2)\n+ self.folder.moveObjectsToTop(["bar", "baz"])\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 2)\n \n def testMoveTwoObjectsToBottom(self):\n- self.folder.moveObjectsToBottom([\'foo\', \'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.moveObjectsToBottom(["foo", "bar"])\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def testRenameObject(self):\n # Renaming should not change position\n transaction.savepoint(optimistic=True) # make rename work\n- self.folder.manage_renameObjects([\'bar\'], [\'barney\'])\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'barney\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.manage_renameObjects(["bar"], ["barney"])\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("barney"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testRenameFirstObject(self):\n # Renaming should not change position\n transaction.savepoint(optimistic=True) # make rename work\n- self.folder.manage_renameObjects([\'foo\'], [\'flintstone\'])\n- self.assertEqual(self.folder.getObjectPosition(\'flintstone\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.manage_renameObjects(["foo"], ["flintstone"])\n+ self.assertEqual(self.folder.getObjectPosition("flintstone"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def testRenameLastObject(self):\n # Renaming should not change position\n transaction.savepoint(optimistic=True) # make rename work\n- self.folder.manage_renameObjects([\'baz\'], [\'bedrock\'])\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bedrock\'), 2)\n+ self.folder.manage_renameObjects(["baz"], ["bedrock"])\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bedrock"), 2)\n \n def testOrderObjects(self):\n- self.folder.orderObjects(\'id\')\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 2)\n+ self.folder.orderObjects("id")\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 2)\n \n def DISABLED_test_manage_move_objects_up(self):\n # Make sure ZMI method works\n- self.folder.manage_move_objects_up(self.app.REQUEST, ids=[\'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.manage_move_objects_up(self.app.REQUEST, ids=["bar"])\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def DISABLED_test_manage_move_objects_down(self):\n # Make sure ZMI method works\n- self.folder.manage_move_objects_down(self.app.REQUEST, ids=[\'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.manage_move_objects_down(self.app.REQUEST, ids=["bar"])\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def DISABLED_test_manage_move_objects_to_top(self):\n # Make sure ZMI method works\n- self.folder.manage_move_objects_to_top(self.app.REQUEST, ids=[\'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.manage_move_objects_to_top(self.app.REQUEST, ids=["bar"])\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n def DISABLED_test_manage_move_objects_to_bottom(self):\n # Make sure ZMI method works\n- self.folder.manage_move_objects_to_bottom(self.app.REQUEST,\n- ids=[\'bar\'])\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.manage_move_objects_to_bottom(self.app.REQUEST, ids=["bar"])\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def testSubsetIds(self):\n- self.folder.moveObjectsByDelta([\'baz\'], -1, [\'foo\', \'bar\', \'baz\'])\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 2)\n+ self.folder.moveObjectsByDelta(["baz"], -1, ["foo", "bar", "baz"])\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 2)\n \n def testSkipObjectsNotInSubsetIds(self):\n- self.folder.moveObjectsByDelta([\'baz\'], -1, [\'foo\', \'baz\'])\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 0)\n+ self.folder.moveObjectsByDelta(["baz"], -1, ["foo", "baz"])\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 0)\n # Did not move\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 2)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 2)\n \n def testIgnoreNonObjects(self):\n # Fix for (http://dev.plone.org/plone/ticket/3959) non contentish\n # objects cause errors, we should just ignore them\n- self.folder.moveObjectsByDelta([\'bar\', \'blah\'], -1)\n- self.assertEqual(self.folder.getObjectPosition(\'bar\'), 0)\n- self.assertEqual(self.folder.getObjectPosition(\'foo\'), 1)\n- self.assertEqual(self.folder.getObjectPosition(\'baz\'), 2)\n+ self.folder.moveObjectsByDelta(["bar", "blah"], -1)\n+ self.assertEqual(self.folder.getObjectPosition("bar"), 0)\n+ self.assertEqual(self.folder.getObjectPosition("foo"), 1)\n+ self.assertEqual(self.folder.getObjectPosition("baz"), 2)\n \n \n class TestOrderSupportInPortal(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n- self.setRoles([\'Manager\'])\n+ self.setRoles(["Manager"])\n # Add a bunch of subobjects we can order later on\n- self.portal.invokeFactory(\'Document\', id=\'foo\')\n- self.portal.invokeFactory(\'Document\', id=\'bar\')\n- self.portal.invokeFactory(\'Document\', id=\'baz\')\n+ self.portal.invokeFactory("Document", id="foo")\n+ self.portal.invokeFactory("Document", id="bar")\n+ self.portal.invokeFactory("Document", id="baz")\n # Move them to the top\n- self.portal.moveObjectsByDelta(ids=[\'foo\', \'bar\', \'baz\'],\n- delta=-len(self.portal),\n- subset_ids=self.portal)\n+ self.portal.moveObjectsByDelta(\n+ ids=["foo", "bar", "baz"], delta=-len(self.portal), subset_ids=self.portal\n+ )\n \n def testRenameObject(self):\n # Renaming should not change position\n transaction.savepoint(optimistic=True) # make rename work\n- self.portal.manage_renameObjects([\'bar\'], [\'barney\'])\n- self.assertEqual(self.portal.getObjectPosition(\'foo\'), 0)\n- self.assertEqual(self.portal.getObjectPosition(\'barney\'), 1)\n- self.assertEqual(self.portal.getObjectPosition(\'baz\'), 2)\n+ self.portal.manage_renameObjects(["bar"], ["barney"])\n+ self.assertEqual(self.portal.getObjectPosition("foo"), 0)\n+ self.assertEqual(self.portal.getObjectPosition("barney"), 1)\n+ self.assertEqual(self.portal.getObjectPosition("baz"), 2)\ndiff --git a/Products/CMFPlone/tests/testPloneTestCase.py b/Products/CMFPlone/tests/testPloneTestCase.py\nindex fcb722afd5..dd90481d8c 100644\n--- a/Products/CMFPlone/tests/testPloneTestCase.py\n+++ b/Products/CMFPlone/tests/testPloneTestCase.py\n@@ -3,36 +3,35 @@\n \n \n class TestPloneTestCase(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n self.catalog = self.portal.portal_catalog\n self.workflow = self.portal.portal_workflow\n self.setupAuthenticator()\n \n def testAddDocument(self):\n- self.assertFalse(self.catalog(id=\'new\'))\n- self.folder.invokeFactory(\'Document\', id=\'new\')\n- self.assertTrue(hasattr(aq_base(self.folder), \'new\'))\n- self.assertTrue(self.catalog(id=\'new\'))\n+ self.assertFalse(self.catalog(id="new"))\n+ self.folder.invokeFactory("Document", id="new")\n+ self.assertTrue(hasattr(aq_base(self.folder), "new"))\n+ self.assertTrue(self.catalog(id="new"))\n \n def testPublishDocument(self):\n- self.folder.invokeFactory(\'Document\', id=\'new\')\n- self.setRoles([\'Reviewer\'])\n- self.workflow.doActionFor(self.folder.new, \'publish\')\n+ self.folder.invokeFactory("Document", id="new")\n+ self.setRoles(["Reviewer"])\n+ self.workflow.doActionFor(self.folder.new, "publish")\n self.assertEqual(\n- self.workflow.getInfoFor(self.folder.new, \'review_state\'),\n- \'published\')\n- self.assertTrue(self.catalog(id=\'new\', review_state=\'published\'))\n+ self.workflow.getInfoFor(self.folder.new, "review_state"), "published"\n+ )\n+ self.assertTrue(self.catalog(id="new", review_state="published"))\n \n def testRetractDocument(self):\n- self.folder.invokeFactory(\'Document\', id=\'new\')\n- self.setRoles([\'Reviewer\'])\n- self.workflow.doActionFor(self.folder.new, \'publish\')\n+ self.folder.invokeFactory("Document", id="new")\n+ self.setRoles(["Reviewer"])\n+ self.workflow.doActionFor(self.folder.new, "publish")\n self.assertEqual(\n- self.workflow.getInfoFor(self.folder.new, \'review_state\'),\n- \'published\')\n- self.setRoles([\'Member\'])\n- self.workflow.doActionFor(self.folder.new, \'retract\')\n+ self.workflow.getInfoFor(self.folder.new, "review_state"), "published"\n+ )\n+ self.setRoles(["Member"])\n+ self.workflow.doActionFor(self.folder.new, "retract")\n self.assertEqual(\n- self.workflow.getInfoFor(self.folder.new, \'review_state\'),\n- \'visible\')\n+ self.workflow.getInfoFor(self.folder.new, "review_state"), "visible"\n+ )\ndiff --git a/Products/CMFPlone/tests/testPloneView.py b/Products/CMFPlone/tests/testPloneView.py\nindex f80af2e4b4..aefe9b297b 100644\n--- a/Products/CMFPlone/tests/testPloneView.py\n+++ b/Products/CMFPlone/tests/testPloneView.py\n@@ -6,10 +6,8 @@\n \n \n class TestPloneView(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n- self.folder.invokeFactory(\'Document\', \'test\',\n- title=\'Test default page\')\n+ self.folder.invokeFactory("Document", "test", title="Test default page")\n self.view = Plone(self.portal, self.app.REQUEST)\n \n def _invalidateRequestMemoizations(self):\n@@ -20,13 +18,13 @@ def _invalidateRequestMemoizations(self):\n \n def testToLocalizedTime(self):\n localdate = self.view.toLocalizedTime\n- value = localdate(\'Mar 9, 1997 1:45pm\', long_format=True)\n- self.assertEqual(value, \'Mar 09, 1997 01:45 PM\')\n+ value = localdate("Mar 9, 1997 1:45pm", long_format=True)\n+ self.assertEqual(value, "Mar 09, 1997 01:45 PM")\n \n def testToLocalizedSize(self):\n tolocalsize = self.view.toLocalizedSize\n value = tolocalsize(3322)\n- self.assertEqual(value, \'3 KB\')\n+ self.assertEqual(value, "3 KB")\n \n def testIsStructuralFolderWithNonFolder(self):\n with warnings.catch_warnings():\n@@ -37,13 +35,13 @@ def testIsStructuralFolderWithNonFolder(self):\n def testIsStructuralFolderWithFolder(self):\n with warnings.catch_warnings():\n warnings.filterwarnings("ignore", category=DeprecationWarning)\n- f = dummy.Folder(\'struct_folder\')\n+ f = dummy.Folder("struct_folder")\n self.assertTrue(Plone(f, self.app.REQUEST).isStructuralFolder())\n \n def testIsStructuralFolderWithNonStructuralFolder(self):\n with warnings.catch_warnings():\n warnings.filterwarnings("ignore", category=DeprecationWarning)\n- f = dummy.NonStructuralFolder(\'ns_folder\')\n+ f = dummy.NonStructuralFolder("ns_folder")\n self.assertFalse(Plone(f, self.app.REQUEST).isStructuralFolder())\n \n def testIsDefaultPageInFolder(self):\n@@ -52,7 +50,7 @@ def testIsDefaultPageInFolder(self):\n view = Plone(self.folder.test, self.app.REQUEST)\n self.assertFalse(view.isDefaultPageInFolder())\n self.assertTrue(self.folder.canSetDefaultPage())\n- self.folder.setDefaultPage(\'test\')\n+ self.folder.setDefaultPage("test")\n # re-create the view, because the old value is cached\n self._invalidateRequestMemoizations()\n view = Plone(self.folder.test, self.app.REQUEST)\n@@ -62,8 +60,9 @@ def testNavigationRootPath(self):\n with warnings.catch_warnings():\n warnings.filterwarnings("ignore", category=DeprecationWarning)\n view = Plone(self.folder, self.app.REQUEST)\n- self.assertEqual(view.navigationRootPath(),\n- self.portal.portal_url.getPortalPath())\n+ self.assertEqual(\n+ view.navigationRootPath(), self.portal.portal_url.getPortalPath()\n+ )\n \n def testNavigationRootUrl(self):\n with warnings.catch_warnings():\n@@ -92,13 +91,13 @@ def testIsFolderOrFolderDefaultPage(self):\n view = Plone(self.folder.test, self.app.REQUEST)\n self.assertFalse(view.isFolderOrFolderDefaultPage())\n # Unless we make it the default view\n- self.folder.setDefaultPage(\'test\')\n+ self.folder.setDefaultPage("test")\n self._invalidateRequestMemoizations()\n view = Plone(self.folder.test, self.app.REQUEST)\n self.assertTrue(view.isFolderOrFolderDefaultPage())\n # And if we have a non-structural folder it should not be true\n- f = dummy.NonStructuralFolder(\'ns_folder\')\n- self.folder._setObject(\'ns_folder\', f)\n+ f = dummy.NonStructuralFolder("ns_folder")\n+ self.folder._setObject("ns_folder", f)\n self._invalidateRequestMemoizations()\n view = Plone(self.folder.ns_folder, self.app.REQUEST)\n self.assertFalse(view.isFolderOrFolderDefaultPage())\n@@ -110,14 +109,15 @@ def testIsPortalOrPortalDefaultPage(self):\n view = Plone(self.portal, self.app.REQUEST)\n self.assertTrue(view.isPortalOrPortalDefaultPage())\n # But not a document\n- self.setRoles([\'Manager\'])\n- self.portal.invokeFactory(\'Document\', \'portal_test\',\n- title=\'Test default page\')\n+ self.setRoles(["Manager"])\n+ self.portal.invokeFactory(\n+ "Document", "portal_test", title="Test default page"\n+ )\n self._invalidateRequestMemoizations()\n view = Plone(self.portal.portal_test, self.app.REQUEST)\n self.assertFalse(view.isPortalOrPortalDefaultPage())\n # Unless we make it the default view\n- self.portal.setDefaultPage(\'portal_test\')\n+ self.portal.setDefaultPage("portal_test")\n self._invalidateRequestMemoizations()\n view = Plone(self.portal.portal_test, self.app.REQUEST)\n self.assertTrue(view.isPortalOrPortalDefaultPage())\n@@ -142,41 +142,41 @@ def testGetCurrentFolder(self):\n self.assertEqual(view.getCurrentFolder(), self.folder)\n \n # A non-structural folder does not count as a folder`\n- f = dummy.NonStructuralFolder(\'ns_folder\')\n- self.folder._setObject(\'ns_folder\', f)\n+ f = dummy.NonStructuralFolder("ns_folder")\n+ self.folder._setObject("ns_folder", f)\n self._invalidateRequestMemoizations()\n view = Plone(self.folder.ns_folder, self.app.REQUEST)\n self.assertEqual(view.getCurrentFolder(), self.folder)\n \n # And even a structural folder that is used as a default page\n # returns its parent\n- self.folder.setDefaultPage(\'ns_folder\')\n+ self.folder.setDefaultPage("ns_folder")\n self._invalidateRequestMemoizations()\n view = Plone(self.folder.ns_folder, self.app.REQUEST)\n self.assertEqual(view.getCurrentFolder(), self.folder)\n \n def testCropText(self):\n view = Plone(self.portal, self.app.REQUEST)\n- self.assertEqual(view.cropText(b\'Hello world\', 7), b\'Hello ...\')\n- self.assertEqual(view.cropText(\'Hello world\', 7), \'Hello ...\')\n- self.assertEqual(view.cropText(b\'Hello world\', 10), b\'Hello worl...\')\n- self.assertEqual(view.cropText(\'Hello world\', 10), \'Hello worl...\')\n- self.assertEqual(view.cropText(b\'Hello world\', 99), b\'Hello world\')\n- self.assertEqual(view.cropText(\'Hello world\', 99), \'Hello world\')\n- self.assertEqual(\n- view.cropText(\'Koko\\u0159\\xedn\', 5), \'Koko\\u0159...\')\n+ self.assertEqual(view.cropText(b"Hello world", 7), b"Hello ...")\n+ self.assertEqual(view.cropText("Hello world", 7), "Hello ...")\n+ self.assertEqual(view.cropText(b"Hello world", 10), b"Hello worl...")\n+ self.assertEqual(view.cropText("Hello world", 10), "Hello worl...")\n+ self.assertEqual(view.cropText(b"Hello world", 99), b"Hello world")\n+ self.assertEqual(view.cropText("Hello world", 99), "Hello world")\n+ self.assertEqual(view.cropText("Koko\\u0159\\xedn", 5), "Koko\\u0159...")\n # Test utf encoded string Kokorin with \'r\' and \'i\' accented\n # Must return 6 characters, because 5th character is two byte\n- text = \'Koko\\u0159\\xedn\'.encode()\n- self.assertEqual(view.cropText(text, 5), b\'Koko\\xc5\\x99...\')\n+ text = "Koko\\u0159\\xedn".encode()\n+ self.assertEqual(view.cropText(text, 5), b"Koko\\xc5\\x99...")\n \n def testSiteEncoding(self):\n with warnings.catch_warnings():\n warnings.filterwarnings("ignore", category=DeprecationWarning)\n view = Plone(self.portal, self.app.REQUEST)\n- self.assertEqual(\'utf-8\', view.site_encoding())\n+ self.assertEqual("utf-8", view.site_encoding())\n \n def test_human_readable_size(self):\n view = Plone(self.portal, self.app.REQUEST)\n from plone.base.utils import human_readable_size\n+\n self.assertIs(view.human_readable_size, human_readable_size)\ndiff --git a/Products/CMFPlone/tests/testPortalCreation.py b/Products/CMFPlone/tests/testPortalCreation.py\nindex bca91df49e..ce3883aadd 100644\n--- a/Products/CMFPlone/tests/testPortalCreation.py\n+++ b/Products/CMFPlone/tests/testPortalCreation.py\n@@ -52,14 +52,14 @@ def afterSetUp(self):\n \n def testInstanceVersion(self):\n # Test if the version of the instance has been set\n- mt = getToolByName(self.portal, \'portal_migration\')\n+ mt = getToolByName(self.portal, "portal_migration")\n self.assertEqual(mt._version, False)\n \n def testProfileVersion(self):\n # The profile version for the base profile should be the same\n # as the file system version and the instance version\n- mt = getToolByName(self.portal, \'portal_migration\')\n- setup = getToolByName(self.portal, \'portal_setup\')\n+ mt = getToolByName(self.portal, "portal_migration")\n+ setup = getToolByName(self.portal, "portal_setup")\n \n version = setup.getVersionForProfile(_DEFAULT_PROFILE)\n instance = mt.getInstanceVersion()\n@@ -69,22 +69,20 @@ def testProfileVersion(self):\n \n def testPloneSkins(self):\n # Plone skins should have been set up\n- self.assertTrue(hasattr(self.folder, \'logo.png\'))\n+ self.assertTrue(hasattr(self.folder, "logo.png"))\n \n def testNoIndexHtmlDocument(self):\n # The portal should not contain an index_html Document\n- self.assertFalse(\'index_html\' in self.portal)\n+ self.assertFalse("index_html" in self.portal)\n \n def testCanViewManagementScreen(self):\n # Make sure the ZMI management screen works\n- self.setRoles([\'Manager\'])\n+ self.setRoles(["Manager"])\n self.portal.manage_main()\n \n def testWorkflowIsActionProvider(self):\n # The workflow tool is one of the last remaining action providers.\n- self.assertTrue(\n- \'portal_workflow\' in self.actions.listActionProviders()\n- )\n+ self.assertTrue("portal_workflow" in self.actions.listActionProviders())\n \n def testPortalIsIndexed(self):\n # The Plone site should be cataloged\n@@ -96,109 +94,101 @@ def testPortalIsIndexed(self):\n def testMembersFolderMetaType(self):\n # Members folder should have meta_type \'Dexterity Container\'\n members = self.membership.getMembersFolder()\n- self.assertEqual(members.meta_type, \'Dexterity Container\')\n+ self.assertEqual(members.meta_type, "Dexterity Container")\n \n def testMembersFolderPortalType(self):\n # Members folder should have portal_type \'Folder\'\n members = self.membership.getMembersFolder()\n- self.assertEqual(members._getPortalTypeName(), \'Folder\')\n+ self.assertEqual(members._getPortalTypeName(), "Folder")\n \n def testMembersFolderMeta(self):\n # Members folder should have title \'Users\'\n members = self.membership.getMembersFolder()\n- self.assertEqual(members.getId(), \'Members\')\n- self.assertEqual(members.Title(), \'Users\')\n+ self.assertEqual(members.getId(), "Members")\n+ self.assertEqual(members.Title(), "Users")\n \n def testMembersFolderIsIndexed(self):\n # Members folder should be cataloged\n- res = self.catalog(getId=\'Members\')\n+ res = self.catalog(getId="Members")\n self.assertEqual(len(res), 1)\n- self.assertEqual(res[0].getId, \'Members\')\n- self.assertEqual(res[0].Title, \'Users\')\n+ self.assertEqual(res[0].getId, "Members")\n+ self.assertEqual(res[0].Title, "Users")\n \n def testMembersFolderOrdering(self):\n # Members folder should not have explicit ordering\n members = self.membership.getMembersFolder()\n- self.assertEqual(members._ordering, \'unordered\')\n+ self.assertEqual(members._ordering, "unordered")\n \n def testMembersFolderDefaultView(self):\n members = self.membership.getMembersFolder()\n- self.assertEqual(members.layout, \'@@member-search\')\n+ self.assertEqual(members.layout, "@@member-search")\n \n def testMailHost(self):\n # MailHost should be of the standard variety\n mailhost = self.portal.MailHost\n- self.assertEqual(mailhost.meta_type, \'Mail Host\')\n+ self.assertEqual(mailhost.meta_type, "Mail Host")\n \n def testFolderEditActionHasEditTitle(self):\n # Edit tab of folders should be named \'edit\', not \'properties\'\n- folder = self.types.getTypeInfo(\'Folder\')\n+ folder = self.types.getTypeInfo("Folder")\n for action in folder._cloneActions():\n- if action.id == \'edit\':\n- self.assertEqual(action.title, \'Edit\')\n+ if action.id == "edit":\n+ self.assertEqual(action.title, "Edit")\n break\n else:\n self.fail("Folder has no \'edit\' action")\n \n def testNoPortalFormTool(self):\n # portal_form should have been removed\n- self.assertFalse(\'portal_form\' in self.portal)\n+ self.assertFalse("portal_form" in self.portal)\n \n def testNoPortalNavigationTool(self):\n # portal_navigation should have been removed\n- self.assertFalse(\'portal_navigation\' in self.portal)\n+ self.assertFalse("portal_navigation" in self.portal)\n \n def testNoFormProperties(self):\n # form_properties should have been removed\n- self.assertFalse(\'form_properties\' in self.properties)\n+ self.assertFalse("form_properties" in self.properties)\n \n def testNoNavigationProperties(self):\n # navigation_properties should have been removed\n- self.assertFalse(\'navigation_properties\' in self.properties)\n+ self.assertFalse("navigation_properties" in self.properties)\n \n def testFormToolTipsProperty(self):\n # formtooltips should have been removed\n- self.assertFalse(self.memberdata.hasProperty(\'formtooltips\'))\n+ self.assertFalse(self.memberdata.hasProperty("formtooltips"))\n \n def testNavTreeProperties(self):\n # navtree_properties should contain the new properties\n self.assertFalse(\n- self.properties.navtree_properties.hasProperty(\n- \'parentMetaTypesNotToQuery\'\n- )\n- )\n- self.assertFalse(\n- self.properties.navtree_properties.hasProperty(\'sitemapDepth\')\n+ self.properties.navtree_properties.hasProperty("parentMetaTypesNotToQuery")\n )\n+ self.assertFalse(self.properties.navtree_properties.hasProperty("sitemapDepth"))\n self.assertFalse(\n- self.properties.navtree_properties.hasProperty(\'showAllParents\')\n+ self.properties.navtree_properties.hasProperty("showAllParents")\n )\n self.assertFalse(\n- self.properties.navtree_properties.hasProperty(\n- \'metaTypesNotToList\'\n- )\n+ self.properties.navtree_properties.hasProperty("metaTypesNotToList")\n ) # noqa\n self.assertFalse(\n- self.properties.navtree_properties.hasProperty(\'sortAttribute\')\n- )\n- self.assertFalse(\n- self.properties.navtree_properties.hasProperty(\'sortOrder\')\n+ self.properties.navtree_properties.hasProperty("sortAttribute")\n )\n+ self.assertFalse(self.properties.navtree_properties.hasProperty("sortOrder"))\n \n registry = getUtility(IRegistry)\n- self.assertTrue(\'plone.workflow_states_to_show\' in registry)\n- self.assertTrue(\'plone.filter_on_workflow\' in registry)\n- self.assertTrue(\'plone.sitemap_depth\' in registry)\n- self.assertTrue(\'plone.root\' in registry)\n- self.assertTrue(\'plone.sort_tabs_on\' in registry)\n- self.assertTrue(\'plone.sort_tabs_reversed\' in registry)\n- self.assertTrue(\'plone.displayed_types\' in registry)\n- self.assertTrue(\'plone.parent_types_not_to_query\' in registry)\n+ self.assertTrue("plone.workflow_states_to_show" in registry)\n+ self.assertTrue("plone.filter_on_workflow" in registry)\n+ self.assertTrue("plone.sitemap_depth" in registry)\n+ self.assertTrue("plone.root" in registry)\n+ self.assertTrue("plone.sort_tabs_on" in registry)\n+ self.assertTrue("plone.sort_tabs_reversed" in registry)\n+ self.assertTrue("plone.displayed_types" in registry)\n+ self.assertTrue("plone.parent_types_not_to_query" in registry)\n \n def testSitemapAction(self):\n # There should be a sitemap action\n for action in self.actions.listActions():\n- if action.getId() == \'sitemap\':\n+ if action.getId() == "sitemap":\n break\n else:\n self.fail("Actions tool has no \'sitemap\' action")\n@@ -207,284 +197,270 @@ def testUnfriendlyTypesProperty(self):\n # We should have an types_not_searched property\n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISearchSchema, prefix="plone")\n- self.assertTrue(\'plone.types_not_searched\' in registry)\n- self.assertTrue(\'Plone Site\' in settings.types_not_searched)\n+ self.assertTrue("plone.types_not_searched" in registry)\n+ self.assertTrue("Plone Site" in settings.types_not_searched)\n \n def testDefaultSortOrderProperty(self):\n # We should have an sort_on property\n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISearchSchema, prefix="plone")\n- self.assertIn(\'plone.sort_on\', registry)\n- self.assertEqual(settings.sort_on, \'relevance\')\n+ self.assertIn("plone.sort_on", registry)\n+ self.assertEqual(settings.sort_on, "relevance")\n \n def testNonDefaultPageTypes(self):\n # We should have a default_page_types setting\n registry = self.portal.portal_registry\n- self.assertIn(\'plone.default_page_types\', registry)\n- self.assertNotIn(\'Folder\', registry[\'plone.default_page_types\'])\n- self.assertIn(\'Document\', registry[\'plone.default_page_types\'])\n+ self.assertIn("plone.default_page_types", registry)\n+ self.assertNotIn("Folder", registry["plone.default_page_types"])\n+ self.assertIn("Document", registry["plone.default_page_types"])\n \n def testNoMembersAction(self):\n # There should not be a Members action\n for action in self.actions.listActions():\n- if action.getId() == \'Members\':\n+ if action.getId() == "Members":\n self.fail("Actions tool still has \'Members\' action")\n \n def testNoNewsAction(self):\n # There should not be a news action\n for action in self.actions.listActions():\n- if action.getId() == \'news\':\n+ if action.getId() == "news":\n self.fail("Actions tool still has \'News\' action")\n \n def testNewsTopicIsIndexed(self):\n # News (smart) folder should be cataloged\n- res = self.catalog(\n- path={\'query\': \'/plone/news/aggregator\', \'depth\': 0}\n- )\n+ res = self.catalog(path={"query": "/plone/news/aggregator", "depth": 0})\n self.assertEqual(len(res), 1)\n- self.assertEqual(res[0].getId, \'aggregator\')\n- self.assertEqual(res[0].Title, \'News\')\n- self.assertEqual(res[0].Description, \'Site News\')\n+ self.assertEqual(res[0].getId, "aggregator")\n+ self.assertEqual(res[0].Title, "News")\n+ self.assertEqual(res[0].Description, "Site News")\n \n def testEventsTopicIsIndexed(self):\n # Events (smart) folder should be cataloged\n- res = self.catalog(\n- path={\'query\': \'/plone/events/aggregator\', \'depth\': 0}\n- )\n+ res = self.catalog(path={"query": "/plone/events/aggregator", "depth": 0})\n self.assertEqual(len(res), 1)\n- self.assertEqual(res[0].getId, \'aggregator\')\n- self.assertEqual(res[0].Title, \'Events\')\n- self.assertEqual(res[0].Description, \'Site Events\')\n+ self.assertEqual(res[0].getId, "aggregator")\n+ self.assertEqual(res[0].Title, "Events")\n+ self.assertEqual(res[0].Description, "Site Events")\n \n def testNewsFolderIsIndexed(self):\n # News folder should be cataloged\n- res = self.catalog(path={\'query\': \'/plone/news\', \'depth\': 0})\n+ res = self.catalog(path={"query": "/plone/news", "depth": 0})\n self.assertEqual(len(res), 1)\n- self.assertEqual(res[0].getId, \'news\')\n- self.assertEqual(res[0].Title, \'News\')\n- self.assertEqual(res[0].Description, \'Site News\')\n+ self.assertEqual(res[0].getId, "news")\n+ self.assertEqual(res[0].Title, "News")\n+ self.assertEqual(res[0].Description, "Site News")\n \n def testEventsFolderIsIndexed(self):\n # Events folder should be cataloged\n- res = self.catalog(path={\'query\': \'/plone/events\', \'depth\': 0})\n+ res = self.catalog(path={"query": "/plone/events", "depth": 0})\n self.assertEqual(len(res), 1)\n- self.assertEqual(res[0].getId, \'events\')\n- self.assertEqual(res[0].Title, \'Events\')\n- self.assertEqual(res[0].Description, \'Site Events\')\n+ self.assertEqual(res[0].getId, "events")\n+ self.assertEqual(res[0].Title, "Events")\n+ self.assertEqual(res[0].Description, "Site Events")\n \n def testNewsFolder(self):\n- self.assertTrue(\'news\' in self.portal.objectIds())\n- folder = getattr(self.portal, \'news\')\n- self.assertEqual(folder.portal_type, \'Folder\')\n- self.assertEqual(folder._ordering, \'unordered\')\n- self.assertEqual(folder.getDefaultPage(), \'aggregator\')\n- self.assertEqual(folder.immediately_addable_types, [\'News Item\'])\n+ self.assertTrue("news" in self.portal.objectIds())\n+ folder = getattr(self.portal, "news")\n+ self.assertEqual(folder.portal_type, "Folder")\n+ self.assertEqual(folder._ordering, "unordered")\n+ self.assertEqual(folder.getDefaultPage(), "aggregator")\n+ self.assertEqual(folder.immediately_addable_types, ["News Item"])\n \n def testEventsFolder(self):\n- self.assertTrue(\'events\' in self.portal.objectIds())\n- folder = getattr(self.portal, \'events\')\n- self.assertEqual(folder.portal_type, \'Folder\')\n- self.assertEqual(folder._ordering, \'unordered\')\n- self.assertEqual(folder.getDefaultPage(), \'aggregator\')\n- self.assertEqual(folder.immediately_addable_types, [\'Event\'])\n+ self.assertTrue("events" in self.portal.objectIds())\n+ folder = getattr(self.portal, "events")\n+ self.assertEqual(folder.portal_type, "Folder")\n+ self.assertEqual(folder._ordering, "unordered")\n+ self.assertEqual(folder.getDefaultPage(), "aggregator")\n+ self.assertEqual(folder.immediately_addable_types, ["Event"])\n \n def testNewsCollection(self):\n # News collection is in place as default view and has a criterion to\n # show only News Items, and uses the folder_summary_view.\n- self.assertEqual(\n- [\'aggregator\'], [i for i in self.portal.news.objectIds()]\n- )\n- collection = getattr(self.portal.news, \'aggregator\')\n- self.assertEqual(collection._getPortalTypeName(), \'Collection\')\n+ self.assertEqual(["aggregator"], [i for i in self.portal.news.objectIds()])\n+ collection = getattr(self.portal.news, "aggregator")\n+ self.assertEqual(collection._getPortalTypeName(), "Collection")\n query = collection.query\n self.assertTrue(\n {\n- \'i\': \'portal_type\',\n- \'o\': \'plone.app.querystring.operation.selection.any\',\n- \'v\': [\'News Item\'],\n+ "i": "portal_type",\n+ "o": "plone.app.querystring.operation.selection.any",\n+ "v": ["News Item"],\n }\n in query\n )\n self.assertTrue(\n {\n- \'i\': \'review_state\',\n- \'o\': \'plone.app.querystring.operation.selection.any\',\n- \'v\': [\'published\'],\n+ "i": "review_state",\n+ "o": "plone.app.querystring.operation.selection.any",\n+ "v": ["published"],\n }\n in query\n )\n- self.assertEqual(collection.getLayout(), \'summary_view\')\n+ self.assertEqual(collection.getLayout(), "summary_view")\n \n def testEventsCollection(self):\n # Events collection is in place as default view and has criterion to\n # show only future Events Items.\n- self.assertEqual(\n- [\'aggregator\'], [i for i in self.portal.events.objectIds()]\n- )\n- collection = getattr(self.portal.events, \'aggregator\')\n- self.assertEqual(collection._getPortalTypeName(), \'Collection\')\n+ self.assertEqual(["aggregator"], [i for i in self.portal.events.objectIds()])\n+ collection = getattr(self.portal.events, "aggregator")\n+ self.assertEqual(collection._getPortalTypeName(), "Collection")\n query = collection.query\n self.assertTrue(\n {\n- \'i\': \'portal_type\',\n- \'o\': \'plone.app.querystring.operation.selection.any\',\n- \'v\': [\'Event\'],\n+ "i": "portal_type",\n+ "o": "plone.app.querystring.operation.selection.any",\n+ "v": ["Event"],\n }\n in query\n )\n self.assertTrue(\n {\n- \'i\': \'review_state\',\n- \'o\': \'plone.app.querystring.operation.selection.any\',\n- \'v\': [\'published\'],\n+ "i": "review_state",\n+ "o": "plone.app.querystring.operation.selection.any",\n+ "v": ["published"],\n }\n in query\n )\n- self.assertEqual(collection.getLayout(), \'event_listing\')\n+ self.assertEqual(collection.getLayout(), "event_listing")\n \n def testObjectButtonActions(self):\n- self.setRoles([\'Manager\', \'Member\'])\n+ self.setRoles(["Manager", "Member"])\n atool = self.actions\n- self.assertFalse(atool.getActionInfo(\'object_buttons/cut\') is None)\n- self.assertFalse(atool.getActionInfo(\'object_buttons/copy\') is None)\n- self.assertFalse(atool.getActionInfo(\'object_buttons/paste\') is None)\n- self.assertFalse(atool.getActionInfo(\'object_buttons/delete\') is None)\n+ self.assertFalse(atool.getActionInfo("object_buttons/cut") is None)\n+ self.assertFalse(atool.getActionInfo("object_buttons/copy") is None)\n+ self.assertFalse(atool.getActionInfo("object_buttons/paste") is None)\n+ self.assertFalse(atool.getActionInfo("object_buttons/delete") is None)\n \n def testContentsTabVisible(self):\n for a in self.actions.listActions():\n- if a.getId() == \'folderContents\':\n+ if a.getId() == "folderContents":\n self.assertTrue(a.visible)\n \n def testDefaultGroupsAdded(self):\n- self.assertTrue(\'Administrators\' in self.groups.listGroupIds())\n- self.assertTrue(\'Reviewers\' in self.groups.listGroupIds())\n+ self.assertTrue("Administrators" in self.groups.listGroupIds())\n+ self.assertTrue("Reviewers" in self.groups.listGroupIds())\n \n def testGenerateTabsSiteProperty(self):\n # The generate_tabs site property should be emtpy\n registry = getUtility(IRegistry)\n- navigation_settings = registry.forInterface(\n- INavigationSchema, prefix="plone"\n- )\n- self.assertTrue(\'plone.generate_tabs\' in registry)\n+ navigation_settings = registry.forInterface(INavigationSchema, prefix="plone")\n+ self.assertTrue("plone.generate_tabs" in registry)\n self.assertTrue(navigation_settings.generate_tabs)\n \n def testSelectableViewsOnFolder(self):\n views = self.portal.portal_types.Folder.getAvailableViewMethods(None)\n- self.assertTrue(\'listing_view\' in views)\n- self.assertTrue(\'album_view\' in views)\n+ self.assertTrue("listing_view" in views)\n+ self.assertTrue("album_view" in views)\n \n def testSelectableViewsOnTopic(self):\n- views = self.portal.portal_types.Collection.getAvailableViewMethods(\n- None\n- )\n- self.assertTrue(\'listing_view\' in views)\n- self.assertTrue(\'album_view\' in views)\n+ views = self.portal.portal_types.Collection.getAvailableViewMethods(None)\n+ self.assertTrue("listing_view" in views)\n+ self.assertTrue("album_view" in views)\n \n def testLocationMemberdataProperty(self):\n # portal_memberdata should have a location property\n- self.assertTrue(self.memberdata.hasProperty(\'location\'))\n+ self.assertTrue(self.memberdata.hasProperty("location"))\n \n def testLanguageMemberdataProperty(self):\n # portal_memberdata should have a language property\n- self.assertTrue(self.memberdata.hasProperty(\'language\'))\n+ self.assertTrue(self.memberdata.hasProperty("language"))\n \n def testDescriptionMemberdataProperty(self):\n # portal_memberdata should have a description property\n- self.assertTrue(self.memberdata.hasProperty(\'description\'))\n+ self.assertTrue(self.memberdata.hasProperty("description"))\n \n def testHome_PageMemberdataProperty(self):\n # portal_memberdata should have a home_page property\n- self.assertTrue(self.memberdata.hasProperty(\'home_page\'))\n+ self.assertTrue(self.memberdata.hasProperty("home_page"))\n \n def testExtEditorMemberdataProperty(self):\n # portal_memberdata should have a location property\n- self.assertEqual(self.memberdata.getProperty(\'ext_editor\'), 0)\n+ self.assertEqual(self.memberdata.getProperty("ext_editor"), 0)\n \n def testSiteSetupActionIsPresent(self):\n actions = self.actions.listActions()\n self.assertEqual(\n- [x.title for x in actions if x.title == \'Site Setup\'],\n- [\'Site Setup\'],\n+ [x.title for x in actions if x.title == "Site Setup"],\n+ ["Site Setup"],\n )\n \n def testEnableLivesearchProperty(self):\n # registry should have enable_livesearch property\n registry = getUtility(IRegistry)\n- self.assertTrue(\'plone.enable_livesearch\' in registry)\n+ self.assertTrue("plone.enable_livesearch" in registry)\n \n def testRedirectLinksProperty(self):\n registry = getUtility(IRegistry)\n- self.assertTrue(\'plone.redirect_links\' in registry)\n- self.assertEqual(True, registry[\'plone.redirect_links\'])\n+ self.assertTrue("plone.redirect_links" in registry)\n+ self.assertEqual(True, registry["plone.redirect_links"])\n \n def testLinkDefaultView(self):\n- self.assertEqual(self.types.Link.default_view, \'link_redirect_view\')\n+ self.assertEqual(self.types.Link.default_view, "link_redirect_view")\n \n def testTTWLockableProperty(self):\n registry = getUtility(IRegistry)\n- self.assertTrue(\'plone.lock_on_ttw_edit\' in registry)\n- self.assertEqual(True, registry[\'plone.lock_on_ttw_edit\'])\n+ self.assertTrue("plone.lock_on_ttw_edit" in registry)\n+ self.assertEqual(True, registry["plone.lock_on_ttw_edit"])\n \n def testPortalFTIIsDynamicFTI(self):\n # Plone Site FTI should be a Dexterity FTI\n fti = self.portal.getTypeInfo()\n- self.assertEqual(fti.meta_type, \'Dexterity FTI\')\n+ self.assertEqual(fti.meta_type, "Dexterity FTI")\n \n def testPloneSiteFTIHasMethodAliases(self):\n # Should add method aliases to the Plone Site FTI\n expected_aliases = {\n- \'(Default)\': \'(dynamic view)\',\n- \'view\': \'(selected layout)\',\n- \'edit\': \'@@edit\',\n- \'sharing\': \'@@sharing\',\n+ "(Default)": "(dynamic view)",\n+ "view": "(selected layout)",\n+ "edit": "@@edit",\n+ "sharing": "@@sharing",\n }\n fti = self.portal.getTypeInfo()\n aliases = fti.getMethodAliases()\n self.assertEqual(aliases, expected_aliases)\n \n def testSiteActions(self):\n- self.setRoles([\'Manager\', \'Member\'])\n+ self.setRoles(["Manager", "Member"])\n atool = self.actions\n- self.assertFalse(atool.getActionInfo(\'site_actions/sitemap\') is None)\n- self.assertFalse(atool.getActionInfo(\'site_actions/contact\') is None)\n- self.assertFalse(\n- atool.getActionInfo(\'site_actions/accessibility\') is None\n- )\n+ self.assertFalse(atool.getActionInfo("site_actions/sitemap") is None)\n+ self.assertFalse(atool.getActionInfo("site_actions/contact") is None)\n+ self.assertFalse(atool.getActionInfo("site_actions/accessibility") is None)\n \n def testSetupAction(self):\n- self.setRoles([\'Manager\', \'Member\'])\n+ self.setRoles(["Manager", "Member"])\n atool = self.actions\n- self.assertFalse(atool.getActionInfo(\'user/plone_setup\') is None)\n+ self.assertFalse(atool.getActionInfo("user/plone_setup") is None)\n \n def testTypesHaveSelectedLayoutViewAction(self):\n # Should add method aliases to the Plone Site FTI\n types = (\n- \'Document\',\n- \'Event\',\n- \'File\',\n- \'Folder\',\n- \'Image\',\n- \'Link\',\n- \'News Item\',\n- \'Collection\',\n- \'Plone Site\',\n+ "Document",\n+ "Event",\n+ "File",\n+ "Folder",\n+ "Image",\n+ "Link",\n+ "News Item",\n+ "Collection",\n+ "Plone Site",\n )\n for typeName in types:\n fti = getattr(self.types, typeName)\n aliases = fti.getMethodAliases()\n- self.assertEqual(aliases[\'view\'], \'(selected layout)\')\n+ self.assertEqual(aliases["view"], "(selected layout)")\n \n def testPortalUsesMethodAliases(self):\n fti = self.portal.getTypeInfo()\n for action in fti.listActions():\n- if action.getId() == \'edit\':\n+ if action.getId() == "edit":\n self.assertEqual(\n- action.getActionExpression(), \'string:${object_url}/edit\'\n+ action.getActionExpression(), "string:${object_url}/edit"\n )\n- if action.getId() == \'sharing\':\n+ if action.getId() == "sharing":\n self.assertEqual(\n action.getActionExpression(),\n- \'string:${object_url}/sharing\',\n+ "string:${object_url}/sharing",\n )\n \n def testNavigationAndSearchPanelsInstalled(self):\n@@ -492,23 +468,21 @@ def testNavigationAndSearchPanelsInstalled(self):\n haveSearch = False\n haveNavigation = False\n for panel in self.cp.listActions():\n- if panel.getId() == \'SearchSettings\':\n+ if panel.getId() == "SearchSettings":\n haveSearch = True\n- elif panel.getId() == \'NavigationSettings\':\n+ elif panel.getId() == "NavigationSettings":\n haveNavigation = True\n self.assertTrue(haveSearch and haveNavigation)\n \n def testOwnerHasAccessInactivePermission(self):\n permission_on_role = [\n p\n- for p in self.portal.permissionsOfRole(\'Owner\')\n- if p[\'name\'] == AccessInactivePortalContent\n+ for p in self.portal.permissionsOfRole("Owner")\n+ if p["name"] == AccessInactivePortalContent\n ][0]\n- self.assertTrue(permission_on_role[\'selected\'])\n- cur_perms = self.portal.permission_settings(\n- AccessInactivePortalContent\n- )[0]\n- self.assertTrue(cur_perms[\'acquire\'])\n+ self.assertTrue(permission_on_role["selected"])\n+ cur_perms = self.portal.permission_settings(AccessInactivePortalContent)[0]\n+ self.assertTrue(cur_perms["acquire"])\n \n def testSyndicationEnabledByDefault(self):\n syn = getMultiAdapter(\n@@ -532,96 +506,95 @@ def testSyndicationEnabledOnNewsAndEvents(self):\n def testSyndicationTabDisabled(self):\n # Syndication tab should be disabled by default\n for action in self.actions.listActions():\n- if action.getId() == \'syndication\' and action.visible:\n- self.fail(\n- "Actions tool still has visible \'syndication\' action"\n- )\n+ if action.getId() == "syndication" and action.visible:\n+ self.fail("Actions tool still has visible \'syndication\' action")\n \n def testObjectButtonActionsInvisibleOnPortalDefaultDocument(self):\n # only a manager would have proper permissions\n- self.setRoles([\'Manager\', \'Member\'])\n- self.portal.invokeFactory(\'Document\', \'index_html\')\n+ self.setRoles(["Manager", "Member"])\n+ self.portal.invokeFactory("Document", "index_html")\n acts = self.actions.listFilteredActionsFor(self.portal.index_html)\n- buttons = acts.get(\'object_buttons\', [])\n+ buttons = acts.get("object_buttons", [])\n self.assertEqual(0, len(buttons))\n \n def testObjectButtonActionsOnDefaultDocumentDoNotApplyToParent(self):\n # only a manager would have proper permissions\n- self.setRoles([\'Manager\', \'Member\'])\n- self.folder.invokeFactory(\'Document\', \'index_html\')\n+ self.setRoles(["Manager", "Member"])\n+ self.folder.invokeFactory("Document", "index_html")\n acts = self.actions.listFilteredActionsFor(self.folder.index_html)\n- buttons = acts[\'object_buttons\']\n+ buttons = acts["object_buttons"]\n self.assertEqual(len(buttons), 5)\n- urls = [a[\'url\'] for a in buttons]\n+ urls = [a["url"] for a in buttons]\n for url in urls:\n self.assertFalse(\n- \'index_html\' not in url,\n- \'Action wrongly applied to parent object %s\' % url,\n+ "index_html" not in url,\n+ "Action wrongly applied to parent object %s" % url,\n ) # noqa\n \n def testObjectButtonActionsPerformCorrectAction(self):\n # only a manager would have proper permissions\n- self.setRoles([\'Manager\', \'Member\'])\n- self.folder.invokeFactory(\'Document\', \'index_html\')\n+ self.setRoles(["Manager", "Member"])\n+ self.folder.invokeFactory("Document", "index_html")\n acts = self.actions.listFilteredActionsFor(self.folder.index_html)\n- buttons = acts[\'object_buttons\']\n+ buttons = acts["object_buttons"]\n self.assertEqual(len(buttons), 5)\n # special case for delete which needs a confirmation form,\n # and for redirection which does not confirm to the url policy,\n # which apparently is that action id X should have url object_X.\n urls = [\n- (a[\'id\'], a[\'url\']) for a in buttons if a[\'id\'] not in\n- (\'delete\', \'redirection\')\n+ (a["id"], a["url"])\n+ for a in buttons\n+ if a["id"] not in ("delete", "redirection")\n ]\n for url in urls:\n # ensure that e.g. the \'copy\' url contains object_copy\n self.assertTrue(\n- \'object_\' + url[0] in url[1],\n- "%s does not perform the expected object_%s action"\n- % (url[0], url[0]),\n+ "object_" + url[0] in url[1],\n+ "%s does not perform the expected object_%s action" % (url[0], url[0]),\n )\n \n- delete_action = [\n- (a[\'id\'], a[\'url\']) for a in buttons if a[\'id\'] == \'delete\'\n- ][0]\n+ delete_action = [(a["id"], a["url"]) for a in buttons if a["id"] == "delete"][0]\n self.assertTrue(\n- \'delete_confirmation\' in delete_action[1],\n+ "delete_confirmation" in delete_action[1],\n "object_delete does not use the confirmation form",\n )\n \n redirection_action = [\n- (a[\'id\'], a[\'url\']) for a in buttons if a[\'id\'] == \'redirection\'\n+ (a["id"], a["url"]) for a in buttons if a["id"] == "redirection"\n ][0]\n- self.assertIn(\'@@manage-aliases\', redirection_action[1])\n+ self.assertIn("@@manage-aliases", redirection_action[1])\n \n def testObjectButtonActionsInExpectedOrder(self):\n # The object buttons need to be in a standardized order\n- self.setRoles([\'Manager\', \'Member\'])\n+ self.setRoles(["Manager", "Member"])\n # fill the copy buffer so we see all actions\n self.folder.cb_dataValid = True\n acts = self.actions.listFilteredActionsFor(self.folder)\n- buttons = acts[\'object_buttons\']\n+ buttons = acts["object_buttons"]\n self.assertEqual(len(buttons), 7)\n- ids = [(a[\'id\']) for a in buttons]\n+ ids = [(a["id"]) for a in buttons]\n self.assertEqual(\n ids,\n- [\'cut\', \'copy\', \'paste\', \'delete\', \'rename\',\n- \'redirection\',\n- \'ical_import_enable\',\n- ],\n+ [\n+ "cut",\n+ "copy",\n+ "paste",\n+ "delete",\n+ "rename",\n+ "redirection",\n+ "ical_import_enable",\n+ ],\n )\n \n def testCustomSkinFolderExists(self):\n # the custom skin needs to be created\n- self.assertTrue(\'custom\' in self.skins)\n+ self.assertTrue("custom" in self.skins)\n \n def testCustomSkinFolderComesFirst(self):\n- firstInDefaultSkin = self.skins.getSkinPath(\'Plone Default\').split(\n- \',\'\n- )[0]\n+ firstInDefaultSkin = self.skins.getSkinPath("Plone Default").split(",")[0]\n self.assertEqual(\n firstInDefaultSkin,\n- \'custom\',\n+ "custom",\n "The \'custom\' layer was not the first in the Plone Default skin. "\n "It was %r." % firstInDefaultSkin,\n )\n@@ -630,33 +603,33 @@ def testMemberHasViewGroupsPermission(self):\n # Member should be granted the \'View Groups\' permission\n member_has_permission = [\n p\n- for p in self.portal.permissionsOfRole(\'Member\')\n- if p[\'name\'] == \'View Groups\'\n+ for p in self.portal.permissionsOfRole("Member")\n+ if p["name"] == "View Groups"\n ][0]\n- self.assertTrue(member_has_permission[\'selected\'])\n+ self.assertTrue(member_has_permission["selected"])\n \n def testDiscussionItemWorkflow(self):\n # By default the discussion item has the comment_one_state_workflow\n self.assertEqual(\n- self.workflow.getChainForPortalType(\'Discussion Item\'),\n- (\'comment_one_state_workflow\',),\n+ self.workflow.getChainForPortalType("Discussion Item"),\n+ ("comment_one_state_workflow",),\n )\n \n def testFolderHasFolderListingView(self):\n # Folder type should allow \'folder_listing\'\n- self.assertTrue(\'listing_view\' in self.types.Folder.view_methods)\n+ self.assertTrue("listing_view" in self.types.Folder.view_methods)\n \n def testFolderHasSummaryView(self):\n # Folder type should allow \'folder_summary_view\'\n- self.assertTrue(\'summary_view\' in self.types.Folder.view_methods)\n+ self.assertTrue("summary_view" in self.types.Folder.view_methods)\n \n def testFolderHasTabularView(self):\n # Folder type should allow \'folder_tabular_view\'\n- self.assertTrue(\'tabular_view\' in self.types.Folder.view_methods)\n+ self.assertTrue("tabular_view" in self.types.Folder.view_methods)\n \n def testFolderHasAlbumView(self):\n # Folder type should allow \'atct_album_view\'\n- self.assertTrue(\'album_view\' in self.types.Folder.view_methods)\n+ self.assertTrue("album_view" in self.types.Folder.view_methods)\n \n def testConfigurableSafeHtmlTransform(self):\n registry = getUtility(IRegistry)\n@@ -665,23 +638,23 @@ def testConfigurableSafeHtmlTransform(self):\n try:\n settings.disable_filtering\n except (AttributeError, KeyError):\n- self.fail(\'Disabling of safe_html should be possible!\')\n+ self.fail("Disabling of safe_html should be possible!")\n \n def testCacheManagers(self):\n # The cache and caching policy managers should exist\n- httpcache = self.portal._getOb(\'HTTPCache\', None)\n- ramcache = self.portal._getOb(\'RAMCache\', None)\n- cpm = self.portal._getOb(\'caching_policy_manager\', None)\n+ httpcache = self.portal._getOb("HTTPCache", None)\n+ ramcache = self.portal._getOb("RAMCache", None)\n+ cpm = self.portal._getOb("caching_policy_manager", None)\n self.assertTrue(isinstance(httpcache, AcceleratedHTTPCacheManager))\n self.assertTrue(isinstance(ramcache, RAMCacheManager))\n self.assertTrue(isinstance(cpm, CachingPolicyManager))\n \n def testHomeActionUsesView(self):\n actions = self.actions.listActions()\n- homeAction = [x for x in actions if x.id == \'index_html\'][0]\n+ homeAction = [x for x in actions if x.id == "index_html"][0]\n self.assertEqual(\n- homeAction.getInfoData()[0][\'url\'].text,\n- \'python:plone_portal_state.navigation_root_url()\',\n+ homeAction.getInfoData()[0]["url"].text,\n+ "python:plone_portal_state.navigation_root_url()",\n )\n \n def testPloneLexicon(self):\n@@ -693,8 +666,8 @@ def testPloneLexicon(self):\n \n def testMakeSnapshot(self):\n # GenericSetup snapshot should work\n- self.setRoles([\'Manager\'])\n- snapshot_id = self.setup._mangleTimestampName(\'test\')\n+ self.setRoles(["Manager"])\n+ snapshot_id = self.setup._mangleTimestampName("test")\n self.setup.createSnapshot(snapshot_id)\n \n def testSiteManagerSetup(self):\n@@ -759,209 +732,192 @@ def testUtilityRegistration(self):\n def testPortletManagersInstalled(self):\n sm = getSiteManager(self.portal)\n registrations = [\n- r.name\n- for r in sm.registeredUtilities()\n- if IPortletManager == r.provided\n+ r.name for r in sm.registeredUtilities() if IPortletManager == r.provided\n ]\n self.assertEqual(\n [\n- \'plone.dashboard1\',\n- \'plone.dashboard2\',\n- \'plone.dashboard3\',\n- \'plone.dashboard4\',\n- \'plone.footerportlets\',\n- \'plone.leftcolumn\',\n- \'plone.rightcolumn\',\n+ "plone.dashboard1",\n+ "plone.dashboard2",\n+ "plone.dashboard3",\n+ "plone.dashboard4",\n+ "plone.footerportlets",\n+ "plone.leftcolumn",\n+ "plone.rightcolumn",\n ],\n sorted(registrations),\n )\n \n def testPortletAssignmentsAtRoot(self):\n- leftColumn = getUtility(IPortletManager, name=\'plone.leftcolumn\')\n- rightColumn = getUtility(IPortletManager, name=\'plone.rightcolumn\')\n+ leftColumn = getUtility(IPortletManager, name="plone.leftcolumn")\n+ rightColumn = getUtility(IPortletManager, name="plone.rightcolumn")\n \n- left = getMultiAdapter(\n- (self.portal, leftColumn), IPortletAssignmentMapping\n- )\n- right = getMultiAdapter(\n- (self.portal, rightColumn), IPortletAssignmentMapping\n- )\n+ left = getMultiAdapter((self.portal, leftColumn), IPortletAssignmentMapping)\n+ right = getMultiAdapter((self.portal, rightColumn), IPortletAssignmentMapping)\n \n self.assertEqual(len(left), 1)\n self.assertEqual(len(right), 2)\n \n def testPortletBlockingForMembersFolder(self):\n members = self.portal.Members\n- rightColumn = getUtility(IPortletManager, name=\'plone.rightcolumn\')\n+ rightColumn = getUtility(IPortletManager, name="plone.rightcolumn")\n portletAssignments = getMultiAdapter(\n (members, rightColumn), ILocalPortletAssignmentManager\n )\n- self.assertEqual(\n- True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS)\n- )\n+ self.assertEqual(True, portletAssignments.getBlacklistStatus(CONTEXT_PORTLETS))\n \n def testAddablePortletsInColumns(self):\n- for name in (\'plone.leftcolumn\', \'plone.rightcolumn\'):\n+ for name in ("plone.leftcolumn", "plone.rightcolumn"):\n column = getUtility(IPortletManager, name=name)\n- addable_types = [\n- p.addview for p in column.getAddablePortletTypes()\n- ]\n+ addable_types = [p.addview for p in column.getAddablePortletTypes()]\n addable_types.sort()\n self.assertEqual(\n [\n- \'plone.portlet.collection.Collection\',\n- \'plone.portlet.static.Static\',\n- \'portlets.Actions\',\n- \'portlets.Calendar\',\n- \'portlets.Classic\',\n- \'portlets.Events\',\n- \'portlets.Login\',\n- \'portlets.Navigation\',\n- \'portlets.News\',\n- \'portlets.Recent\',\n- \'portlets.Review\',\n- \'portlets.Search\',\n- \'portlets.rss\',\n+ "plone.portlet.collection.Collection",\n+ "plone.portlet.static.Static",\n+ "portlets.Actions",\n+ "portlets.Calendar",\n+ "portlets.Classic",\n+ "portlets.Events",\n+ "portlets.Login",\n+ "portlets.Navigation",\n+ "portlets.News",\n+ "portlets.Recent",\n+ "portlets.Review",\n+ "portlets.Search",\n+ "portlets.rss",\n ],\n addable_types,\n )\n \n def testAddablePortletsInDashboard(self):\n for name in (\n- \'plone.dashboard1\',\n- \'plone.dashboard2\',\n- \'plone.dashboard3\',\n- \'plone.dashboard4\',\n+ "plone.dashboard1",\n+ "plone.dashboard2",\n+ "plone.dashboard3",\n+ "plone.dashboard4",\n ):\n column = getUtility(IPortletManager, name=name)\n- addable_types = [\n- p.addview for p in column.getAddablePortletTypes()\n- ]\n+ addable_types = [p.addview for p in column.getAddablePortletTypes()]\n addable_types.sort()\n self.assertEqual(\n [\n- \'plone.portlet.collection.Collection\',\n- \'plone.portlet.static.Static\',\n- \'portlets.Actions\',\n- \'portlets.Calendar\',\n- \'portlets.Classic\',\n- \'portlets.Events\',\n- \'portlets.News\',\n- \'portlets.Recent\',\n- \'portlets.Review\',\n- \'portlets.Search\',\n- \'portlets.rss\',\n+ "plone.portlet.collection.Collection",\n+ "plone.portlet.static.Static",\n+ "portlets.Actions",\n+ "portlets.Calendar",\n+ "portlets.Classic",\n+ "portlets.Events",\n+ "portlets.News",\n+ "portlets.Recent",\n+ "portlets.Review",\n+ "portlets.Search",\n+ "portlets.rss",\n ],\n addable_types,\n )\n \n def testReaderEditorRoles(self):\n- self.assertTrue(\'Reader\' in self.portal.valid_roles())\n- self.assertTrue(\'Editor\' in self.portal.valid_roles())\n+ self.assertTrue("Reader" in self.portal.valid_roles())\n+ self.assertTrue("Editor" in self.portal.valid_roles())\n self.assertTrue(\n- \'Reader\' in self.portal.acl_users.portal_role_manager.listRoleIds()\n+ "Reader" in self.portal.acl_users.portal_role_manager.listRoleIds()\n )\n self.assertTrue(\n- \'Editor\' in self.portal.acl_users.portal_role_manager.listRoleIds()\n+ "Editor" in self.portal.acl_users.portal_role_manager.listRoleIds()\n )\n self.assertTrue(\n- \'View\'\n+ "View"\n in [\n- r[\'name\']\n- for r in self.portal.permissionsOfRole(\'Reader\')\n- if r[\'selected\']\n+ r["name"]\n+ for r in self.portal.permissionsOfRole("Reader")\n+ if r["selected"]\n ]\n )\n self.assertTrue(\n- \'Modify portal content\'\n+ "Modify portal content"\n in [\n- r[\'name\']\n- for r in self.portal.permissionsOfRole(\'Editor\')\n- if r[\'selected\']\n+ r["name"]\n+ for r in self.portal.permissionsOfRole("Editor")\n+ if r["selected"]\n ]\n )\n \n def testWorkflowsInstalled(self):\n for wf in [\n- \'intranet_workflow\',\n- \'intranet_folder_workflow\',\n- \'one_state_workflow\',\n- \'simple_publication_workflow\',\n+ "intranet_workflow",\n+ "intranet_folder_workflow",\n+ "one_state_workflow",\n+ "simple_publication_workflow",\n ]:\n self.assertTrue(wf in self.portal.portal_workflow)\n \n def testAddPermisssionsGivenToContributorRole(self):\n- self.assertTrue(\'Contributor\' in self.portal.valid_roles())\n+ self.assertTrue("Contributor" in self.portal.valid_roles())\n self.assertTrue(\n- \'Contributor\'\n- in self.portal.acl_users.portal_role_manager.listRoleIds()\n+ "Contributor" in self.portal.acl_users.portal_role_manager.listRoleIds()\n )\n for p in [\n- \'Add portal content\',\n- \'Add portal folders\',\n- \'plone.app.contenttypes: Add Document\',\n- \'plone.app.contenttypes: Add Event\',\n- \'plone.app.contenttypes: Add File\',\n- \'plone.app.contenttypes: Add Folder\',\n- \'plone.app.contenttypes: Add Link\',\n- \'plone.app.contenttypes: Add News Item\',\n+ "Add portal content",\n+ "Add portal folders",\n+ "plone.app.contenttypes: Add Document",\n+ "plone.app.contenttypes: Add Event",\n+ "plone.app.contenttypes: Add File",\n+ "plone.app.contenttypes: Add Folder",\n+ "plone.app.contenttypes: Add Link",\n+ "plone.app.contenttypes: Add News Item",\n ]:\n self.assertTrue(\n p\n in [\n- r[\'name\']\n- for r in self.portal.permissionsOfRole(\'Contributor\')\n- if r[\'selected\']\n+ r["name"]\n+ for r in self.portal.permissionsOfRole("Contributor")\n+ if r["selected"]\n ]\n )\n \n def testSharingAction(self):\n # Should be in portal_actions\n- self.assertTrue(\'local_roles\' in self.actions.object)\n+ self.assertTrue("local_roles" in self.actions.object)\n \n # Should not be in any of the default FTIs\n for fti in self.types.values():\n- self.assertFalse(\n- \'local_roles\' in [a.id for a in fti.listActions()]\n- )\n+ self.assertFalse("local_roles" in [a.id for a in fti.listActions()])\n \n def testSecondaryEditorPermissionsGivenToEditorRole(self):\n for p in [\n- \'Manage properties\',\n- \'Modify view template\',\n- \'Request review\',\n+ "Manage properties",\n+ "Modify view template",\n+ "Request review",\n ]:\n self.assertTrue(\n p\n in [\n- r[\'name\']\n- for r in self.portal.permissionsOfRole(\'Editor\')\n- if r[\'selected\']\n+ r["name"]\n+ for r in self.portal.permissionsOfRole("Editor")\n+ if r["selected"]\n ]\n )\n \n def testNonFolderishTabsProperty(self):\n registry = getUtility(IRegistry)\n- navigation_settings = registry.forInterface(\n- INavigationSchema, prefix="plone"\n- )\n+ navigation_settings = registry.forInterface(INavigationSchema, prefix="plone")\n self.assertEqual(True, navigation_settings.nonfolderish_tabs)\n \n def testNoDoubleGenericSetupImportSteps(self):\n view = ImportStepsView(self.setup, None)\n- self.assertEqual([i[\'id\'] for i in view.doubleSteps()], [])\n+ self.assertEqual([i["id"] for i in view.doubleSteps()], [])\n \n def testNoInvalidGenericSetupImportSteps(self):\n view = ImportStepsView(self.setup, None)\n- self.assertEqual([i[\'id\'] for i in view.invalidSteps()], [])\n+ self.assertEqual([i["id"] for i in view.invalidSteps()], [])\n \n def testNoDoubleGenericSetupExportSteps(self):\n view = ExportStepsView(self.setup, None)\n- self.assertEqual([i[\'id\'] for i in view.doubleSteps()], [])\n+ self.assertEqual([i["id"] for i in view.doubleSteps()], [])\n \n def testNoInvalidGenericSetupExportSteps(self):\n view = ExportStepsView(self.setup, None)\n- self.assertEqual([i[\'id\'] for i in view.invalidSteps()], [])\n+ self.assertEqual([i["id"] for i in view.invalidSteps()], [])\n \n \n class TestPortalBugs(PloneTestCase.PloneTestCase):\n@@ -984,8 +940,8 @@ def testFinalStepsWithMembersFolderDeleted(self):\n # is gone\n self.loginAsPortalOwner()\n portal = self.portal\n- portal.manage_delObjects([\'Members\'])\n- setup_tool = getToolByName(self.portal, \'portal_setup\')\n+ portal.manage_delObjects(["Members"])\n+ setup_tool = getToolByName(self.portal, "portal_setup")\n setuphandlers.importFinalSteps(setup_tool) # raises error if fail\n self.assertTrue(1 == 1)\n \n@@ -995,9 +951,9 @@ def afterSetUp(self):\n self.properties = self.portal.portal_properties\n \n def testManagementPageCharset(self):\n- manage_charset = getattr(self.portal, \'management_page_charset\', None)\n+ manage_charset = getattr(self.portal, "management_page_charset", None)\n self.assertTrue(manage_charset)\n- self.assertEqual(manage_charset, \'utf-8\')\n+ self.assertEqual(manage_charset, "utf-8")\n \n \n class TestAddPloneSite(PloneTestCase.PloneTestCase):\n@@ -1008,23 +964,23 @@ def addsite(self):\n self.loginAsPortalOwner()\n # Set up a request for the plone-addsite view.\n form = self.request.form\n- form[\'form.submitted\'] = 1\n- form[\'site_id\'] = \'plonesite1\'\n- form[\'setup_content\'] = 1\n- self.request[\'_authenticator\'] = createToken()\n- addsite = self.app.restrictedTraverse(\'@@plone-addsite\')\n+ form["form.submitted"] = 1\n+ form["site_id"] = "plonesite1"\n+ form["setup_content"] = 1\n+ self.request["_authenticator"] = createToken()\n+ addsite = self.app.restrictedTraverse("@@plone-addsite")\n addsite()\n \n def test_addsite_en_as_nl(self):\n # Add an English site with a Dutch browser.\n- self.request[\'HTTP_ACCEPT_LANGUAGE\'] = \'nl\'\n- self.request.form[\'default_language\'] = \'en\'\n+ self.request["HTTP_ACCEPT_LANGUAGE"] = "nl"\n+ self.request.form["default_language"] = "en"\n self.addsite()\n plonesite = self.app.plonesite1\n # Unfortunately, the next test passes even without the fix (overriding\n # HTTP_ACCEPT_LANGUAGE on the request in factory.py). This seems to be\n # because translations are not available in the tests.\n- self.assertIn(\'Learn more about Plone\', plonesite.text.raw)\n+ self.assertIn("Learn more about Plone", plonesite.text.raw)\n \n # XXX maybe it is better to reset the sire in the @@plone-addsite view\n # or somewhere else?\ndiff --git a/Products/CMFPlone/tests/testQueryCatalog.py b/Products/CMFPlone/tests/testQueryCatalog.py\nindex 5657c6bc71..09fd22ccad 100644\n--- a/Products/CMFPlone/tests/testQueryCatalog.py\n+++ b/Products/CMFPlone/tests/testQueryCatalog.py\n@@ -29,7 +29,7 @@ def stripStuff(self, query_dict):\n # auto-set with types blacklisting. Useful to simplify test\n # assertions when we don\'t care\n if isinstance(query_dict, dict):\n- for ignore in [\'portal_type\', \'show_inactive\']:\n+ for ignore in ["portal_type", "show_inactive"]:\n if ignore in query_dict:\n del query_dict[ignore]\n return query_dict\n@@ -39,110 +39,84 @@ def afterSetUp(self):\n \n def testEmptyRequest(self):\n request = {}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)), [])\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), [])\n \n def testNonexistantIndex(self):\n- request = {\'foo\': \'bar\'}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)), [])\n+ request = {"foo": "bar"}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), [])\n \n def testRealIndex(self):\n- request = {\'SearchableText\': \'bar\'}\n+ request = {"SearchableText": "bar"}\n self.assertEqual(\n self.stripStuff(self.folder.queryCatalog(request)),\n- {\'SearchableText\': \'bar\'}\n+ {"SearchableText": "bar"},\n )\n \n def testTwoIndexes(self):\n- request = {\'SearchableText\': \'bar\', \'foo\': \'bar\'}\n+ request = {"SearchableText": "bar", "foo": "bar"}\n self.assertEqual(\n self.stripStuff(self.folder.queryCatalog(request)),\n- {\'SearchableText\': \'bar\'}\n+ {"SearchableText": "bar"},\n )\n \n def testRealIndexes(self):\n- request = {\'SearchableText\': \'bar\', \'Subject\': \'bar\'}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)),\n- request\n- )\n+ request = {"SearchableText": "bar", "Subject": "bar"}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), request)\n \n def testOnlySort(self):\n # if we only sort, we shouldn\'t actually call the catalog\n- request = {\'sort_on\': \'foozle\'}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)), [])\n- request = {\'sort_order\': \'foozle\', \'sort_on\': \'foozle\'}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)), [])\n- request = {\'sort_order\': \'foozle\'}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)), [])\n+ request = {"sort_on": "foozle"}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), [])\n+ request = {"sort_order": "foozle", "sort_on": "foozle"}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), [])\n+ request = {"sort_order": "foozle"}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), [])\n \n def testOnlyUsage(self):\n- request = {\'date_usage\': \'range:min\'}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)), [])\n+ request = {"date_usage": "range:min"}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), [])\n \n def testRealWithUsage(self):\n- request = {\'modified\': \'2004-01-01\', \'modified_usage\': \'range:min\'}\n- expected = {\'modified\': {\'query\': \'2004-01-01\', \'range\': \'min\'}}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)),\n- expected\n- )\n+ request = {"modified": "2004-01-01", "modified_usage": "range:min"}\n+ expected = {"modified": {"query": "2004-01-01", "range": "min"}}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), expected)\n \n def testSortLimit(self):\n # the script ignored \'sort_limit\'; test to show it no longer does.\n- request = {\'SearchableText\': \'bar\',\n- \'sort_on\': \'foozle\',\n- \'sort_limit\': 50}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)),\n- request\n- )\n+ request = {"SearchableText": "bar", "sort_on": "foozle", "sort_limit": 50}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), request)\n \n def testBlacklistedTypes(self):\n- request = {\'SearchableText\': \'a*\'}\n+ request = {"SearchableText": "a*"}\n registry = getUtility(IRegistry)\n search_settings = registry.forInterface(ISearchSchema, prefix="plone")\n- search_settings.types_not_searched = (\'Event\',)\n+ search_settings.types_not_searched = ("Event",)\n qry = self.folder.queryCatalog(request, use_types_blacklist=True)\n- self.assertTrue(\'Document\' in qry[\'portal_type\'])\n- self.assertTrue(\'Event\' not in qry[\'portal_type\'])\n+ self.assertTrue("Document" in qry["portal_type"])\n+ self.assertTrue("Event" not in qry["portal_type"])\n \n def testNavigationRoot(self):\n- request = {\'SearchableText\': \'a*\'}\n+ request = {"SearchableText": "a*"}\n registry = getUtility(IRegistry)\n- navigation_settings = registry.forInterface(\n- INavigationSchema,\n- prefix=\'plone\'\n- )\n- navigation_settings.root = \'/\'\n+ navigation_settings = registry.forInterface(INavigationSchema, prefix="plone")\n+ navigation_settings.root = "/"\n qry = self.folder.queryCatalog(request, use_navigation_root=True)\n- self.assertEqual(\'/\'.join(self.portal.getPhysicalPath()), qry[\'path\'])\n- self.setRoles((\'Manager\',))\n- self.portal.invokeFactory(\'Folder\', \'foo\')\n- navigation_settings.root = \'/foo\'\n+ self.assertEqual("/".join(self.portal.getPhysicalPath()), qry["path"])\n+ self.setRoles(("Manager",))\n+ self.portal.invokeFactory("Folder", "foo")\n+ navigation_settings.root = "/foo"\n qry = self.folder.queryCatalog(request, use_navigation_root=True)\n- self.assertEqual(\n- \'/\'.join(self.portal.foo.getPhysicalPath()),\n- qry[\'path\']\n- )\n+ self.assertEqual("/".join(self.portal.foo.getPhysicalPath()), qry["path"])\n \n def testNavigationRootDoesNotOverrideExplicitPath(self):\n- request = {\'SearchableText\': \'a*\', \'path\': \'/yyy/zzz\'}\n- self.setRoles((\'Manager\',))\n- self.portal.invokeFactory(\'Folder\', \'foo\')\n+ request = {"SearchableText": "a*", "path": "/yyy/zzz"}\n+ self.setRoles(("Manager",))\n+ self.portal.invokeFactory("Folder", "foo")\n registry = getUtility(IRegistry)\n- navigation_settings = registry.forInterface(\n- INavigationSchema,\n- prefix=\'plone\'\n- )\n- navigation_settings.root = \'/\'\n+ navigation_settings = registry.forInterface(INavigationSchema, prefix="plone")\n+ navigation_settings.root = "/"\n qry = self.folder.queryCatalog(request, use_navigation_root=True)\n- self.assertEqual(\'/yyy/zzz\', qry[\'path\'])\n+ self.assertEqual("/yyy/zzz", qry["path"])\n \n \n class TestQueryCatalogQuoting(PloneTestCase.PloneTestCase):\n@@ -163,7 +137,7 @@ def stripStuff(self, query_dict):\n # auto-set with types blacklisting. Useful to simplify test\n # assertions when we don\'t care\n if isinstance(query_dict, dict):\n- for ignore in [\'portal_type\', \'show_inactive\']:\n+ for ignore in ["portal_type", "show_inactive"]:\n if ignore in query_dict:\n del query_dict[ignore]\n return query_dict\n@@ -172,125 +146,121 @@ def afterSetUp(self):\n self.portal.portal_catalog.__call__ = self.dummyCatalog\n \n def testQuotingNone(self):\n- request = {\'SearchableText\': \'Hello Joel\'}\n+ request = {"SearchableText": "Hello Joel"}\n expected = request\n self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request, quote_logic=1)),\n- expected)\n+ self.stripStuff(self.folder.queryCatalog(request, quote_logic=1)), expected\n+ )\n \n def testQuotingNotNeeded(self):\n- request = {\'SearchableText\': \'Hello or Joel\'}\n+ request = {"SearchableText": "Hello or Joel"}\n expected = request\n self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request, quote_logic=1)),\n- expected)\n+ self.stripStuff(self.folder.queryCatalog(request, quote_logic=1)), expected\n+ )\n \n def testQuotingNotNeededWithNot(self):\n- request = {\'SearchableText\': \'Hello or not Joel\'}\n+ request = {"SearchableText": "Hello or not Joel"}\n expected = request\n self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request, quote_logic=1)),\n- expected)\n+ self.stripStuff(self.folder.queryCatalog(request, quote_logic=1)), expected\n+ )\n \n def testQuotingRequiredToEscape(self):\n- request = {\'SearchableText\': \'Hello Joel Or\'}\n- expected = {\'SearchableText\': \'Hello Joel "Or"\'}\n+ request = {"SearchableText": "Hello Joel Or"}\n+ expected = {"SearchableText": \'Hello Joel "Or"\'}\n self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request, quote_logic=1)),\n- expected)\n+ self.stripStuff(self.folder.queryCatalog(request, quote_logic=1)), expected\n+ )\n \n def testQuotingRequiredToEscapeOptionOff(self):\n- request = {\'SearchableText\': \'Hello Joel Or\'}\n+ request = {"SearchableText": "Hello Joel Or"}\n expected = request\n- self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)),\n- expected)\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), expected)\n \n def testQuotingWithLeadingNot(self):\n- request = {\'SearchableText\': \'Not Hello Joel\'}\n+ request = {"SearchableText": "Not Hello Joel"}\n expected = request\n- self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)),\n- expected)\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), expected)\n \n def testEmptyItem(self):\n- request = {\'SearchableText\': \'\'}\n+ request = {"SearchableText": ""}\n # queryCatalog will return empty result without calling the catalog\n # tool\n expected = []\n- self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)),\n- expected)\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), expected)\n \n def testEmptyItemShowAll(self):\n- request = {\'SearchableText\': \'\'}\n+ request = {"SearchableText": ""}\n # Catalog gets a blank search, and returns the empty dict\n expected = {}\n self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request, show_all=1)),\n- expected)\n+ self.stripStuff(self.folder.queryCatalog(request, show_all=1)), expected\n+ )\n \n def testBadCharsAreQuoted(self):\n- request = {\'SearchableText\': \'context(1)\'}\n+ request = {"SearchableText": "context(1)"}\n # Catalog gets ( or ) in search and quotes them to avoid parse error\n- expected = {\'SearchableText\': \'context"("1")"\'}\n- self.assertEqual(\n- self.stripStuff(self.folder.queryCatalog(request)),\n- expected)\n+ expected = {"SearchableText": \'context"("1")"\'}\n+ self.assertEqual(self.stripStuff(self.folder.queryCatalog(request)), expected)\n \n \n class TestQueryCatalogParseError(PloneTestCase.PloneTestCase):\n """Checks that the queryCatalog script returns an empty result set\n- in case of ZCTextIndex ParseErrors.\n+ in case of ZCTextIndex ParseErrors.\n \n- This testcase uses the real catalog, not a stub.\n+ This testcase uses the real catalog, not a stub.\n """\n \n def afterSetUp(self):\n self.folder.invokeFactory(\n- \'Document\', id=\'doc\', text=RichTextValue(\'foo bar baz\'))\n+ "Document", id="doc", text=RichTextValue("foo bar baz")\n+ )\n \n def testSearchableText(self):\n- request = {\'SearchableText\': \'foo\'}\n+ request = {"SearchableText": "foo"}\n # We expect a non-empty result set\n self.assertTrue(self.portal.queryCatalog(request))\n \n def testParseError(self):\n # ZCTextIndex raises ParseError\n- self.assertRaises(ParseError, self.portal.portal_catalog,\n- SearchableText=\'-foo\')\n+ self.assertRaises(ParseError, self.portal.portal_catalog, SearchableText="-foo")\n \n def testQueryCatalogParseError(self):\n- request = {\'SearchableText\': \'-foo\'}\n+ request = {"SearchableText": "-foo"}\n # ZCTextIndex raises ParseError which translates to empty result\n expected = []\n self.assertEqual(self.portal.queryCatalog(request), expected)\n \n def testQueryCatalogParseError3050(self):\n # http://dev.plone.org/plone/ticket/3050\n- request = {\'SearchableText\': \'AND\'}\n+ request = {"SearchableText": "AND"}\n # ZCTextIndex raises ParseError which translates to empty result\n expected = []\n self.assertEqual(self.portal.queryCatalog(request), expected)\n \n \n-AddPortalTopics = \'Add portal topics\'\n+AddPortalTopics = "Add portal topics"\n \n \n class TestSearchForms(PloneTestCase.PloneTestCase):\n """Render all forms related to queryCatalog"""\n \n def testRenderSearchForm(self):\n- searchView = getMultiAdapter((self.portal, self.app.REQUEST),\n- name="search")\n+ searchView = getMultiAdapter((self.portal, self.app.REQUEST), name="search")\n searchView()\n \n def testRenderSearchRSS(self):\n- searchRssView = getMultiAdapter((self.portal, self.app.REQUEST),\n- name="search_rss")\n+ searchRssView = getMultiAdapter(\n+ (self.portal, self.app.REQUEST), name="search_rss"\n+ )\n searchRssView()\n \n def testSearchGives404WhenDisabled(self):\n registry = getUtility(IRegistry)\n settings = registry.forInterface(ISiteSyndicationSettings)\n settings.search_rss_enabled = False\n- searchRssView = getMultiAdapter((self.portal, self.app.REQUEST),\n- name="search_rss")\n+ searchRssView = getMultiAdapter(\n+ (self.portal, self.app.REQUEST), name="search_rss"\n+ )\n self.assertRaises(NotFound, searchRssView)\ndiff --git a/Products/CMFPlone/tests/testRegistrationTool.py b/Products/CMFPlone/tests/testRegistrationTool.py\nindex f811068627..c7f872bd1c 100644\n--- a/Products/CMFPlone/tests/testRegistrationTool.py\n+++ b/Products/CMFPlone/tests/testRegistrationTool.py\n@@ -15,7 +15,7 @@\n import unittest\n \n \n-member_id = \'new_member\'\n+member_id = "new_member"\n \n try:\n # Python 3\n@@ -26,87 +26,113 @@\n \n \n class TestRegistrationTool(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n self.registration = self.portal.portal_registration\n- self.portal.acl_users.userFolderAddUser("userid", "password",\n- (), (), ())\n+ self.portal.acl_users.userFolderAddUser("userid", "password", (), (), ())\n self.portal.acl_users._doAddGroup("groupid", ())\n \n def testJoinCreatesUser(self):\n- self.registration.addMember(member_id, TEST_USER_PASSWORD,\n- properties={\'username\': member_id,\n- \'email\': \'foo@bar.com\'})\n+ self.registration.addMember(\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={"username": member_id, "email": "foo@bar.com"},\n+ )\n user = self.portal.acl_users.getUserById(member_id)\n- self.assertTrue(user, \'addMember failed to create user\')\n+ self.assertTrue(user, "addMember failed to create user")\n \n def testCannotRegisterWithRootAdminUsername(self):\n root_user = self.portal.aq_parent.acl_users.users.listUserIds()[0]\n- self.assertRaises(ValueError,\n- self.registration.addMember,\n- root_user, TEST_USER_PASSWORD,\n- properties={\'username\': root_user,\n- \'email\': \'foo@bar.com\'})\n+ self.assertRaises(\n+ ValueError,\n+ self.registration.addMember,\n+ root_user,\n+ TEST_USER_PASSWORD,\n+ properties={"username": root_user, "email": "foo@bar.com"},\n+ )\n \n def testJoinWithUppercaseEmailCreatesUser(self):\n- self.registration.addMember(member_id, TEST_USER_PASSWORD,\n- properties={\'username\': member_id,\n- \'email\': \'FOO@BAR.COM\'})\n+ self.registration.addMember(\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={"username": member_id, "email": "FOO@BAR.COM"},\n+ )\n user = self.portal.acl_users.getUserById(member_id)\n- self.assertTrue(user, \'addMember failed to create user\')\n+ self.assertTrue(user, "addMember failed to create user")\n \n def testJoinWithoutEmailRaisesValueError(self):\n- self.assertRaises(ValueError,\n- self.registration.addMember,\n- member_id, TEST_USER_PASSWORD,\n- properties={\'username\': member_id, \'email\': \'\'})\n+ self.assertRaises(\n+ ValueError,\n+ self.registration.addMember,\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={"username": member_id, "email": ""},\n+ )\n \n def testJoinWithBadEmailRaisesValueError(self):\n- self.assertRaises(ValueError,\n- self.registration.addMember,\n- member_id, TEST_USER_PASSWORD,\n- properties={\n- \'username\': member_id,\n- \'email\': \'foo@bar.com, fred@bedrock.com\'})\n+ self.assertRaises(\n+ ValueError,\n+ self.registration.addMember,\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={\n+ "username": member_id,\n+ "email": "foo@bar.com, fred@bedrock.com",\n+ },\n+ )\n \n def testJoinAsExistingMemberRaisesValueError(self):\n- self.assertRaises(ValueError,\n- self.registration.addMember,\n- PloneTestCase.default_user, TEST_USER_PASSWORD,\n- properties={\'username\': \'Dr FooBar\',\n- \'email\': \'foo@bar.com\'})\n+ self.assertRaises(\n+ ValueError,\n+ self.registration.addMember,\n+ PloneTestCase.default_user,\n+ TEST_USER_PASSWORD,\n+ properties={"username": "Dr FooBar", "email": "foo@bar.com"},\n+ )\n \n def testJoinAsExistingNonMemberUserRaisesValueError(self):\n # http://dev.plone.org/plone/ticket/3221\n self.portal.acl_users._doAddUser(member_id, TEST_USER_PASSWORD, [], [])\n- self.assertRaises(ValueError,\n- self.registration.addMember,\n- member_id, TEST_USER_PASSWORD,\n- properties={\'username\': member_id,\n- \'email\': \'foo@bar.com\'})\n+ self.assertRaises(\n+ ValueError,\n+ self.registration.addMember,\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={"username": member_id, "email": "foo@bar.com"},\n+ )\n \n def testJoinWithPortalIdAsUsernameRaisesValueError(self):\n- self.assertRaises(ValueError,\n- self.registration.addMember,\n- self.portal.getId(), TEST_USER_PASSWORD,\n- properties={\'username\': \'Dr FooBar\',\n- \'email\': \'foo@bar.com\'})\n+ self.assertRaises(\n+ ValueError,\n+ self.registration.addMember,\n+ self.portal.getId(),\n+ TEST_USER_PASSWORD,\n+ properties={"username": "Dr FooBar", "email": "foo@bar.com"},\n+ )\n \n def testJoinWithoutPermissionRaisesUnauthorized(self):\n # http://dev.plone.org/plone/ticket/3000\n- self.portal.manage_permission(AddPortalMember, [\'Manager\'], acquire=0)\n- self.assertRaises(Unauthorized,\n- self.registration.restrictedTraverse, \'addMember\')\n+ self.portal.manage_permission(AddPortalMember, ["Manager"], acquire=0)\n+ self.assertRaises(\n+ Unauthorized, self.registration.restrictedTraverse, "addMember"\n+ )\n \n def testTestPasswordValidityConfirm(self):\n # https://dev.plone.org/ticket/13325\n- self.assertTrue(self.registration.testPasswordValidity(\n- \'validpassword\', confirm=None) is None)\n- self.assertFalse(self.registration.testPasswordValidity(\n- \'validpassword\', confirm=\'anotherpassword\') is None)\n+ self.assertTrue(\n+ self.registration.testPasswordValidity("validpassword", confirm=None)\n+ is None\n+ )\n+ self.assertFalse(\n+ self.registration.testPasswordValidity(\n+ "validpassword", confirm="anotherpassword"\n+ )\n+ is None\n+ )\n \n def testTestPasswordValidityPolicy(self):\n- self.assertIsNone(self.registration.testPasswordValidity(TEST_USER_PASSWORD, confirm=None))\n+ self.assertIsNone(\n+ self.registration.testPasswordValidity(TEST_USER_PASSWORD, confirm=None)\n+ )\n self.assertEqual(\n self.registration.testPasswordValidity("abcd", confirm=None),\n "Your password must contain at least ${min_chars} characters.",\n@@ -119,43 +145,47 @@ def testTestPasswordValidityPolicy(self):\n )\n \n def testPasValidation(self):\n- self.assertIsNone(self.registration.pasValidation("password", TEST_USER_PASSWORD))\n+ self.assertIsNone(\n+ self.registration.pasValidation("password", TEST_USER_PASSWORD)\n+ )\n self.assertEqual(\n self.registration.pasValidation("password", "abcd"),\n "Your password must contain at least ${min_chars} characters.",\n )\n \n def testNewIdAllowed(self):\n- self.assertEqual(self.registration.isMemberIdAllowed(\'newuser\'), 1)\n+ self.assertEqual(self.registration.isMemberIdAllowed("newuser"), 1)\n \n def testTakenUserId(self):\n- self.assertEqual(self.registration.isMemberIdAllowed(\'userid\'), 0)\n+ self.assertEqual(self.registration.isMemberIdAllowed("userid"), 0)\n \n def testTakenGroupd(self):\n- self.assertEqual(self.registration.isMemberIdAllowed(\'groupid\'), 0)\n+ self.assertEqual(self.registration.isMemberIdAllowed("groupid"), 0)\n \n def testIsMemberIdAllowedIfSubstringOfExisting(self):\n # http://dev.plone.org/plone/ticket/6396\n- self.assertTrue(self.registration.isMemberIdAllowed(\'useri\'))\n+ self.assertTrue(self.registration.isMemberIdAllowed("useri"))\n \n def testRegisteredNotify(self):\n # tests email sending on registration\n # First install a fake mailhost utility\n- mails = self.portal.MailHost = MockMailHost(\'MailHost\')\n+ mails = self.portal.MailHost = MockMailHost("MailHost")\n sm = getSiteManager(self.portal)\n sm.unregisterUtility(provided=IMailHost)\n sm.registerUtility(mails, IMailHost)\n # Register a user\n- self.registration.addMember(member_id, TEST_USER_PASSWORD,\n- properties={\'username\': member_id,\n- \'email\': \'foo@bar.com\'})\n+ self.registration.addMember(\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={"username": member_id, "email": "foo@bar.com"},\n+ )\n \n registry = getUtility(IRegistry)\n- site_settings = registry.forInterface(ISiteSchema, prefix=\'plone\')\n- site_settings.site_title = \'T\xc3\xabst Portal\'\n+ site_settings = registry.forInterface(ISiteSchema, prefix="plone")\n+ site_settings.site_title = "T\xc3\xabst Portal"\n mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n- mail_settings.email_from_name = \'T\xc3\xabst Admin\'\n- mail_settings.email_from_address = \'bar@baz.com\'\n+ mail_settings.email_from_name = "T\xc3\xabst Admin"\n+ mail_settings.email_from_address = "bar@baz.com"\n \n # Notify the registered user\n self.registration.registeredNotify(member_id)\n@@ -163,31 +193,32 @@ def testRegisteredNotify(self):\n msg = message_from_bytes(mails.messages[0])\n # We get an encoded subject\n self.assertEqual(\n- msg[\'Subject\'],\n- \'=?utf-8?q?User_Account_Information_for_T=C3=ABst_Portal?=\')\n+ msg["Subject"], "=?utf-8?q?User_Account_Information_for_T=C3=ABst_Portal?="\n+ )\n # Also a partially encoded from header\n- self.assertEqual(msg[\'From\'],\n- \'=?utf-8?q?T=C3=ABst_Admin?= \')\n- self.assertEqual(msg[\'Content-Type\'], \'text/plain; charset="utf-8"\')\n+ self.assertEqual(msg["From"], "=?utf-8?q?T=C3=ABst_Admin?= ")\n+ self.assertEqual(msg["Content-Type"], \'text/plain; charset="utf-8"\')\n \n def testRegisteredNotifyEncoding(self):\n- mails = self.portal.MailHost = MockMailHost(\'MailHost\')\n+ mails = self.portal.MailHost = MockMailHost("MailHost")\n sm = getSiteManager(self.portal)\n sm.unregisterUtility(provided=IMailHost)\n sm.registerUtility(mails, IMailHost)\n # Register a user\n- self.registration.addMember(member_id, TEST_USER_PASSWORD,\n- properties={\'username\': member_id,\n- \'email\': \'foo@bar.com\'})\n+ self.registration.addMember(\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={"username": member_id, "email": "foo@bar.com"},\n+ )\n registry = getUtility(IRegistry)\n- site_settings = registry.forInterface(ISiteSchema, prefix=\'plone\')\n- site_settings.site_title = \'Test Portal\'\n+ site_settings = registry.forInterface(ISiteSchema, prefix="plone")\n+ site_settings.site_title = "Test Portal"\n mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n- mail_settings.email_from_name = \'Test Admin\'\n- mail_settings.email_from_address = \'bar@baz.com\'\n+ mail_settings.email_from_name = "Test Admin"\n+ mail_settings.email_from_address = "bar@baz.com"\n \n # Set the portal email encoding\n- mail_settings.email_charset = \'us-ascii\'\n+ mail_settings.email_charset = "us-ascii"\n \n # Notify the registered user\n self.registration.registeredNotify(member_id)\n@@ -195,71 +226,74 @@ def testRegisteredNotifyEncoding(self):\n msg = message_from_bytes(mails.messages[0])\n \n # Ensure charset (and thus Content-Type) were set via template\n- self.assertEqual(msg[\'Content-Type\'], \'text/plain; charset="us-ascii"\')\n+ self.assertEqual(msg["Content-Type"], \'text/plain; charset="us-ascii"\')\n \n def testMailPassword(self):\n # tests email sending for password emails\n # First install a fake mailhost utility\n- mails = self.portal.MailHost = MockMailHost(\'MailHost\')\n+ mails = self.portal.MailHost = MockMailHost("MailHost")\n sm = getSiteManager(self.portal)\n sm.unregisterUtility(provided=IMailHost)\n sm.registerUtility(mails, IMailHost)\n # Register a user\n- self.registration.addMember(member_id, TEST_USER_PASSWORD,\n- properties={\'username\': member_id,\n- \'email\': \'foo@bar.com\'})\n+ self.registration.addMember(\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={"username": member_id, "email": "foo@bar.com"},\n+ )\n \n registry = getUtility(IRegistry)\n- site_settings = registry.forInterface(ISiteSchema, prefix=\'plone\')\n- site_settings.site_title = \'T\xc3\xabst Portal\'\n+ site_settings = registry.forInterface(ISiteSchema, prefix="plone")\n+ site_settings.site_title = "T\xc3\xabst Portal"\n mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n- mail_settings.email_from_name = \'T\xc3\xabst Admin\'\n- mail_settings.email_from_address = \'bar@baz.com\'\n+ mail_settings.email_from_name = "T\xc3\xabst Admin"\n+ mail_settings.email_from_address = "bar@baz.com"\n \n from zope.publisher.browser import TestRequest\n+\n self.registration.mailPassword(member_id, TestRequest())\n self.assertEqual(len(mails.messages), 1)\n msg = message_from_bytes(mails.messages[0])\n # We get an encoded subject\n- self.assertEqual(msg[\'Subject\'],\n- \'=?utf-8?q?Password_reset_request?=\')\n+ self.assertEqual(msg["Subject"], "=?utf-8?q?Password_reset_request?=")\n # Also a partially encoded from header\n- self.assertEqual(msg[\'From\'],\n- \'=?utf-8?q?T=C3=ABst_Admin?= \')\n- self.assertEqual(msg[\'Content-Type\'], \'text/plain; charset="utf-8"\')\n+ self.assertEqual(msg["From"], "=?utf-8?q?T=C3=ABst_Admin?= ")\n+ self.assertEqual(msg["Content-Type"], \'text/plain; charset="utf-8"\')\n \n def testMailPasswordEncoding(self):\n # tests email sending for password emails\n # First install a fake mailhost utility\n- mails = self.portal.MailHost = MockMailHost(\'MailHost\')\n+ mails = self.portal.MailHost = MockMailHost("MailHost")\n sm = getSiteManager(self.portal)\n sm.unregisterUtility(provided=IMailHost)\n sm.registerUtility(mails, IMailHost)\n # Register a user\n- self.registration.addMember(member_id, TEST_USER_PASSWORD,\n- properties={\'username\': member_id,\n- \'email\': \'foo@bar.com\'})\n+ self.registration.addMember(\n+ member_id,\n+ TEST_USER_PASSWORD,\n+ properties={"username": member_id, "email": "foo@bar.com"},\n+ )\n registry = getUtility(IRegistry)\n- site_settings = registry.forInterface(ISiteSchema, prefix=\'plone\')\n- site_settings.site_title = \'T\xc3\xabst Portal\'\n+ site_settings = registry.forInterface(ISiteSchema, prefix="plone")\n+ site_settings.site_title = "T\xc3\xabst Portal"\n mail_settings = registry.forInterface(IMailSchema, prefix="plone")\n- mail_settings.email_from_name = \'Test Admin\'\n- mail_settings.email_from_address = \'bar@baz.com\'\n+ mail_settings.email_from_name = "Test Admin"\n+ mail_settings.email_from_address = "bar@baz.com"\n \n # Set the portal email encoding\n- self.assertEqual(mail_settings.email_charset, \'utf-8\')\n+ self.assertEqual(mail_settings.email_charset, "utf-8")\n \n from zope.publisher.browser import TestRequest\n+\n self.registration.mailPassword(member_id, TestRequest())\n self.assertEqual(len(mails.messages), 1)\n msg = message_from_bytes(mails.messages[0])\n \n # Ensure charset (and thus Content-Type) were set via template\n- self.assertEqual(msg[\'Content-Type\'], \'text/plain; charset="utf-8"\')\n+ self.assertEqual(msg["Content-Type"], \'text/plain; charset="utf-8"\')\n \n \n class TestPasswordGeneration(PloneTestCase.PloneTestCase):\n-\n def afterSetUp(self):\n self.registration = self.portal.portal_registration\n \n@@ -268,7 +302,7 @@ def testMD5BaseAttribute(self):\n # fall back to the class attribute and its default value.\n self.registration._md5base()\n self.assertNotEqual(self.registration._v_md5base, None)\n- delattr(self.registration, \'_v_md5base\')\n+ delattr(self.registration, "_v_md5base")\n self.assertEqual(self.registration._v_md5base, None)\n \n def testGetRandomPassword(self):\n@@ -276,7 +310,7 @@ def testGetRandomPassword(self):\n self.assertEqual(len(pw), 6)\n \n def testGetDeterministicPassword(self):\n- salt = \'foo\'\n+ salt = "foo"\n pw = self.registration.getPassword(6, salt)\n self.assertEqual(len(pw), 6)\n # Passing in the same length and salt should give the same\n@@ -285,7 +319,7 @@ def testGetDeterministicPassword(self):\n self.assertEqual(pw, self.registration.getPassword(6, salt))\n # These should fail\n self.assertNotEqual(pw, self.registration.getPassword(7, salt))\n- self.assertNotEqual(pw, self.registration.getPassword(6, salt + \'x\'))\n+ self.assertNotEqual(pw, self.registration.getPassword(6, salt + "x"))\n \n def testGeneratePassword(self):\n pw = self.registration.generatePassword()\n@@ -293,13 +327,12 @@ def testGeneratePassword(self):\n self.assertTrue(len(pw) >= 20)\n \n def testGenerateResetCode(self):\n- salt = \'foo\'\n+ salt = "foo"\n rc = self.registration.generateResetCode(salt)\n self.assertEqual(rc, self.registration.generateResetCode(salt))\n \n \n class TestEmailValidityChecker(unittest.TestCase):\n-\n check = lambda _, email: _checkEmail(email)\n \n def test_generic_tld(self):\n@@ -320,5 +353,4 @@ def test_long_tld(self):\n \n \n class TestRegistrationToolEmailValidityChecker(PloneTestCase.PloneTestCase):\n-\n check = lambda _, email: _.portal.portal_registration.isValidEmail(email)\ndiff --git a/Products/CMFPlone/tests/testResourceRegistries.py b/Products/CMFPlone/tests/testResourceRegistries.py\nindex 211bce6912..fb3ccce34c 100644\n--- a/Products/CMFPlone/tests/testResourceRegistries.py\n+++ b/Products/CMFPlone/tests/testResourceRegistries.py\n@@ -296,7 +296,6 @@ def test_remove_bundle_on_request_with_subrequest(self):\n \n \n class TestExpressions(PloneTestCase.PloneTestCase):\n-\n def setUp(self):\n # Add three bundles with three different expressions.\n registry = getUtility(IRegistry)\n@@ -409,21 +408,26 @@ def test_scripts_switching_roles(self):\n \n \n class TestRRControlPanel(PloneTestCase.PloneTestCase):\n-\n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- self.app = self.layer[\'app\']\n+ self.portal = self.layer["portal"]\n+ self.app = self.layer["app"]\n self.browser = Browser(self.app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n+ )\n+ self.browser.open(\n+ self.portal.absolute_url() + "/@@resourceregistry-controlpanel"\n )\n- self.browser.open(self.portal.absolute_url() + "/@@resourceregistry-controlpanel")\n \n def test_controlpanel(self):\n- self.assertIn("Resource Registry ", self.browser.contents)\n- self.assertIn("++plone++static/bundle-plone/bundle.min.js", self.browser.contents)\n+ self.assertIn(\n+ \'Resource Registry \',\n+ self.browser.contents,\n+ )\n+ self.assertIn(\n+ "++plone++static/bundle-plone/bundle.min.js", self.browser.contents\n+ )\n \n def test_add_resource(self):\n # the last form is the add form\n@@ -434,7 +438,7 @@ def test_add_resource(self):\n add_form.getControl("add").click()\n \n self.assertIn(\n- "
\')\n+ self.assertEqual(pt.pt_render(), "access
Secret.
")\n \n # Check the same for anonymous.\n logout()\n- self.assertRaises(\n- Unauthorized, guarded_getattr, self.portal, \'foobar\')\n- self.assertRaises(\n- Unauthorized, guarded_getattr, self.portal.foobar, \'text\')\n+ self.assertRaises(Unauthorized, guarded_getattr, self.portal, "foobar")\n+ self.assertRaises(Unauthorized, guarded_getattr, self.portal.foobar, "text")\n # *If* somehow anonymous can access the text, then we have allowed\n # access to the output as well.\n self.assertEqual(\n- guarded_getattr(self.portal.foobar.text, \'output\'),\n- \'Secret.
\')\n+ guarded_getattr(self.portal.foobar.text, "output"), "Secret.
"\n+ )\n # But for the template anonymous would need access to everything,\n # which rightly fails.\n self.assertRaises(Unauthorized, pt.pt_render)\n \n # Test the simpler access without str.format for the current user.\n login(self.portal, TEST_USER_NAME)\n- pt = ZopePageTemplate(\n- \'mytemplate\', TEMPLATE %\n- "context.foobar.text.output")\n+ pt = ZopePageTemplate("mytemplate", TEMPLATE % "context.foobar.text.output")\n hack_pt(pt, context=self.portal)\n- self.assertEqual(pt.pt_render(), \'
Secret.
\')\n+ self.assertEqual(pt.pt_render(), "
Secret.
")\n \n # and for anonymous\n logout()\n@@ -191,11 +193,12 @@ def test_access_to_private_content_not_allowed_via_rich_text(self):\n def test_access_to_private_content_not_allowed_in_any_way(self):\n # This is a more general version of the rich text one.\n from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate\n- foobar = create_private_document(self.portal, \'foobar\')\n+\n+ foobar = create_private_document(self.portal, "foobar")\n login(self.portal, TEST_USER_NAME)\n self.assertEqual(\n- self.portal.portal_workflow.getInfoFor(foobar, \'review_state\'),\n- \'private\')\n+ self.portal.portal_workflow.getInfoFor(foobar, "review_state"), "private"\n+ )\n TEMPLATE = \'
\'\n \n # attribute access\n@@ -203,51 +206,42 @@ def test_access_to_private_content_not_allowed_in_any_way(self):\n # say \'bound method DexterityContent.Title\', without giving the actual title,\n # but there may be other attributes that give worse info.\n pt = ZopePageTemplate(\n- \'mytemplate\', TEMPLATE %\n- "\'access {0.foobar.Title}\'.format(context)")\n+ "mytemplate", TEMPLATE % "\'access {0.foobar.Title}\'.format(context)"\n+ )\n hack_pt(pt, context=self.portal)\n login(self.portal, TEST_USER_NAME)\n- method_name = \'DexterityContent.Title\'\n+ method_name = "DexterityContent.Title"\n self.assertEqual(\n pt.pt_render(),\n- \'access >
\' % method_name)\n+ "access >
" % method_name,\n+ )\n logout()\n self.assertRaises(Unauthorized, pt.pt_render)\n \n # key access\n- pt = ZopePageTemplate(\n- \'mytemplate\', TEMPLATE %\n- "\'{0[foobar]}\'.format(context)")\n+ pt = ZopePageTemplate("mytemplate", TEMPLATE % "\'{0[foobar]}\'.format(context)")\n hack_pt(pt, context=self.portal)\n login(self.portal, TEST_USER_NAME)\n- self.assertEqual(\n- pt.pt_render(),\n- \'
\')\n+ self.assertEqual(pt.pt_render(), "
")\n logout()\n self.assertRaises(Unauthorized, pt.pt_render)\n \n # Prepare a list so we can test item access.\n self.portal.testlist = [foobar]\n- pt = ZopePageTemplate(\n- \'mytemplate\', TEMPLATE %\n- "\'{0.testlist}\'.format(context)")\n+ pt = ZopePageTemplate("mytemplate", TEMPLATE % "\'{0.testlist}\'.format(context)")\n hack_pt(pt, context=self.portal)\n # If you have such a list, you *can* see an id.\n- self.assertEqual(\n- pt.pt_render(),\n- \'[]
\')\n+ self.assertEqual(pt.pt_render(), "[]
")\n # But you cannot access an item.\n pt = ZopePageTemplate(\n- \'mytemplate\', TEMPLATE %\n- "\'{0.testlist[0]}\'.format(context)")\n+ "mytemplate", TEMPLATE % "\'{0.testlist[0]}\'.format(context)"\n+ )\n hack_pt(pt, context=self.portal)\n self.assertRaises(Unauthorized, pt.pt_render)\n # except as authenticated user\n login(self.portal, TEST_USER_NAME)\n- self.assertEqual(\n- pt.pt_render(),\n- \'
\')\n+ self.assertEqual(pt.pt_render(), "
")\n \n # Zope 3 templates are always file system templates. So we actually have\n # no problems allowing str.format there.\n@@ -256,23 +250,23 @@ def test_cook_zope3_page_templates_normal(self):\n from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile\n \n # Note: on Plone 3.3 this is actually a ZopeTwoPageTemplateFile.\n- pt = ViewPageTemplateFile(\'normal_zope3_page_template.pt\')\n+ pt = ViewPageTemplateFile("normal_zope3_page_template.pt")\n hack_pt(pt)\n # Need to pass a namespace.\n- namespace = {\'context\': self.portal}\n+ namespace = {"context": self.portal}\n self.assertEqual(\n pt.pt_render(namespace).strip(),\n- \'<plonesite at plone>
\\n\'\n- \'<PLONESITE AT PLONE>
\')\n+ "<plonesite at plone>
\\n" "<PLONESITE AT PLONE>
",\n+ )\n \n def test_cook_zope3_page_templates_using_format(self):\n from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile\n \n # Note: on Plone 3.3 this is actually a ZopeTwoPageTemplateFile.\n- pt = ViewPageTemplateFile(\'using_format_zope3_page_template.pt\')\n+ pt = ViewPageTemplateFile("using_format_zope3_page_template.pt")\n hack_pt(pt)\n # Need to pass a namespace.\n- namespace = {\'context\': self.portal}\n+ namespace = {"context": self.portal}\n self.assertEqual(\n pt.pt_render(namespace).strip(),\n "class of <plonesite at plone> is "\n@@ -282,7 +276,7 @@ def test_cook_zope3_page_templates_using_format(self):\n "
{\'foo\': 42} has foo=42
\\n"\n "{\'foo\': 42} has foo=42
\\n"\n "[\'ni\'] has first item ni
\\n"\n- "[\'ni\'] has first item ni
"\n+ "[\'ni\'] has first item ni
",\n )\n \n \n@@ -296,14 +290,15 @@ def test_safe_format_properly_applied(self):\n from AccessControl.SimpleObjectPolicies import ContainerAssertions\n \n import types\n+\n ca = ContainerAssertions\n self.assertTrue(str in ca)\n self.assertTrue(isinstance(ca[str], dict))\n- self.assertTrue(\'format\' in ca[str])\n- string_rule = ca[str][\'format\']\n+ self.assertTrue("format" in ca[str])\n+ string_rule = ca[str]["format"]\n self.assertTrue(isinstance(string_rule, types.FunctionType))\n # Take less steps for unicode.\n- unicode_rule = ca[str][\'format\']\n+ unicode_rule = ca[str]["format"]\n self.assertTrue(isinstance(unicode_rule, types.FunctionType))\n self.assertEqual(string_rule, unicode_rule)\n \n@@ -317,8 +312,8 @@ def test_standard_error_message(self):\n # For good measure we check this in Plone 4.3 too.\n \n response = self.publish(\n- \'/plone/standard_error_message\',\n- env={\'HTTP_ACCEPT\': \'application/json\'})\n+ "/plone/standard_error_message", env={"HTTP_ACCEPT": "application/json"}\n+ )\n \n # This should *not* return a 302 Unauthorized. We expect a 404. Or\n # really a 200, because we explicitly call the standard_error_message\n@@ -329,51 +324,59 @@ def test_standard_error_message(self):\n \n def test_cook_zope2_page_templates_bad_key_str(self):\n from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate\n- pt = ZopePageTemplate(\'mytemplate\', BAD_KEY_STR)\n+\n+ pt = ZopePageTemplate("mytemplate", BAD_KEY_STR)\n hack_pt(pt, self.portal)\n- create_private_document(self.portal, \'secret\')\n+ create_private_document(self.portal, "secret")\n login(self.portal, TEST_USER_NAME)\n self.assertEqual(\n- pt.pt_render().replace(\'ATDocument\', \'Document\'),\n- \'access by key: <Document at secret>
\')\n+ pt.pt_render().replace("ATDocument", "Document"),\n+ "access by key: <Document at secret>
",\n+ )\n logout()\n self.assertRaises(Unauthorized, pt.pt_render)\n \n def test_cook_zope2_page_templates_bad_key_unicode(self):\n from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate\n- pt = ZopePageTemplate(\'mytemplate\', BAD_KEY_UNICODE)\n+\n+ pt = ZopePageTemplate("mytemplate", BAD_KEY_UNICODE)\n hack_pt(pt, self.portal)\n- create_private_document(self.portal, \'secret\')\n+ create_private_document(self.portal, "secret")\n login(self.portal, TEST_USER_NAME)\n self.assertEqual(\n- pt.pt_render().replace(\'ATDocument\', \'Document\'),\n- \'access by key: <Document at secret>
\')\n+ pt.pt_render().replace("ATDocument", "Document"),\n+ "access by key: <Document at secret>
",\n+ )\n logout()\n self.assertRaises(Unauthorized, pt.pt_render)\n \n def test_cook_zope2_page_templates_bad_item_str(self):\n from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate\n- secret = create_private_document(self.portal, \'secret\')\n+\n+ secret = create_private_document(self.portal, "secret")\n login(self.portal, TEST_USER_NAME)\n self.portal.testlist = [secret]\n- pt = ZopePageTemplate(\'mytemplate\', BAD_ITEM_STR)\n+ pt = ZopePageTemplate("mytemplate", BAD_ITEM_STR)\n hack_pt(pt, self.portal.testlist)\n self.assertEqual(\n- pt.pt_render().replace(\'ATDocument\', \'Document\'),\n- \'access by item: <Document at secret>
\')\n+ pt.pt_render().replace("ATDocument", "Document"),\n+ "access by item: <Document at secret>
",\n+ )\n logout()\n self.assertRaises(Unauthorized, pt.pt_render)\n \n def test_cook_zope2_page_templates_bad_item_unicode(self):\n from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate\n- secret = create_private_document(self.portal, \'secret\')\n+\n+ secret = create_private_document(self.portal, "secret")\n login(self.portal, TEST_USER_NAME)\n self.portal.testlist = [secret]\n- pt = ZopePageTemplate(\'mytemplate\', BAD_ITEM_UNICODE)\n+ pt = ZopePageTemplate("mytemplate", BAD_ITEM_UNICODE)\n hack_pt(pt, self.portal.testlist)\n self.assertEqual(\n- pt.pt_render().replace(\'ATDocument\', \'Document\'),\n- \'access by item: <Document at secret>
\')\n+ pt.pt_render().replace("ATDocument", "Document"),\n+ "access by item: <Document at secret>
",\n+ )\n logout()\n self.assertRaises(Unauthorized, pt.pt_render)\n \n@@ -382,7 +385,7 @@ def assert_is_checked_via_security_manager(self, pt_content):\n from AccessControl.SecurityManager import setSecurityPolicy\n from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate\n \n- pt = ZopePageTemplate(\'mytemplate\', pt_content)\n+ pt = ZopePageTemplate("mytemplate", pt_content)\n noSecurityManager()\n old_security_policy = setSecurityPolicy(UnauthorizedSecurityPolicy())\n try:\n@@ -393,7 +396,8 @@ def assert_is_checked_via_security_manager(self, pt_content):\n \n def test_getattr_access_is_checked_via_security_manager(self):\n self.assert_is_checked_via_security_manager(\n- """
""")\n+ """
"""\n+ )\n \n def test_getitem_access_is_checked_via_security_manager(self):\n self.assert_is_checked_via_security_manager(\ndiff --git a/Products/CMFPlone/tests/test_sitelogo.py b/Products/CMFPlone/tests/test_sitelogo.py\nindex c47e14130c..1e15bbb21e 100644\n--- a/Products/CMFPlone/tests/test_sitelogo.py\n+++ b/Products/CMFPlone/tests/test_sitelogo.py\n@@ -7,35 +7,38 @@\n \n \n # Red pixel with filename pixel.png\n-SITE_LOGO_BASE64 = b\'filenameb64:cGl4ZWwucG5n;datab64:iVBORw0KGgoAAAANSUhEUgA\'\\\n- b\'AAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAA\'\\\n- b\'AAElFTkSuQmCC\'\n+SITE_LOGO_BASE64 = (\n+ b"filenameb64:cGl4ZWwucG5n;datab64:iVBORw0KGgoAAAANSUhEUgA"\n+ b"AAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAA"\n+ b"AAElFTkSuQmCC"\n+)\n \n-SITE_LOGO_HEX = b\'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR\\x00\\x00\\x00\\x01\\x00\\x00\'\\\n- b\'\\x00\\x01\\x08\\x02\\x00\\x00\\x00\\x90wS\\xde\\x00\\x00\\x00\\x0cIDAT\'\\\n- b\'\\x08\\xd7c\\xf8\\xcf\\xc0\\x00\\x00\\x03\\x01\\x01\\x00\\x18\\xdd\\x8d\'\\\n- b\'\\xb0\\x00\\x00\\x00\\x00IEND\\xaeB`\\x82\'\n+SITE_LOGO_HEX = (\n+ b"\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR\\x00\\x00\\x00\\x01\\x00\\x00"\n+ b"\\x00\\x01\\x08\\x02\\x00\\x00\\x00\\x90wS\\xde\\x00\\x00\\x00\\x0cIDAT"\n+ b"\\x08\\xd7c\\xf8\\xcf\\xc0\\x00\\x00\\x03\\x01\\x01\\x00\\x18\\xdd\\x8d"\n+ b"\\xb0\\x00\\x00\\x00\\x00IEND\\xaeB`\\x82"\n+)\n \n \n class SiteLogoFunctionalTest(unittest.TestCase):\n- """Test the site logo view.\n- """\n+ """Test the site logo view."""\n+\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n+ self.portal = self.layer["portal"]\n \n def test_sitelogo_view(self):\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ISiteSchema, prefix=\'plone\')\n+ settings = registry.forInterface(ISiteSchema, prefix="plone")\n settings.site_logo = SITE_LOGO_BASE64\n- view = self.portal.restrictedTraverse(\'@@site-logo\')\n+ view = self.portal.restrictedTraverse("@@site-logo")\n self.assertEqual(view(), SITE_LOGO_HEX)\n view.request.response\n headers = view.request.response\n- self.assertEqual(headers[\'content-type\'], \'image/png\')\n- self.assertEqual(headers[\'content-length\'], \'69\')\n+ self.assertEqual(headers["content-type"], "image/png")\n+ self.assertEqual(headers["content-length"], "69")\n self.assertEqual(\n- headers[\'content-disposition\'],\n- "attachment; filename*=UTF-8\'\'pixel.png"\n+ headers["content-disposition"], "attachment; filename*=UTF-8\'\'pixel.png"\n )\ndiff --git a/Products/CMFPlone/tests/test_sitemap.py b/Products/CMFPlone/tests/test_sitemap.py\nindex 8e9bc76a48..b3971a2737 100644\n--- a/Products/CMFPlone/tests/test_sitemap.py\n+++ b/Products/CMFPlone/tests/test_sitemap.py\n@@ -11,49 +11,46 @@\n \n \n class ProductsCMFPloneSetupTest(unittest.TestCase):\n-\n layer = PLONE_APP_CONTENTTYPES_FUNCTIONAL_TESTING\n \n def setUp(self):\n- app = self.layer[\'app\']\n- self.portal = self.layer[\'portal\']\n- self.request = self.layer[\'request\']\n+ app = self.layer["app"]\n+ self.portal = self.layer["portal"]\n+ self.request = self.layer["request"]\n self.portal_url = self.portal.absolute_url()\n \n self.browser = Browser(app)\n self.browser.handleErrors = False\n self.browser.addHeader(\n- \'Authorization\',\n- f\'Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}\'\n+ "Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}"\n )\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n \n def test_sitemap(self):\n- self.portal.invokeFactory(\'Document\', \'doc1\', title="Document 1")\n- self.portal.invokeFactory(\'Document\', \'doc2\', title="Document 2")\n- self.portal.invokeFactory(\'Document\', \'doc3\', title="Document 3")\n+ self.portal.invokeFactory("Document", "doc1", title="Document 1")\n+ self.portal.invokeFactory("Document", "doc2", title="Document 2")\n+ self.portal.invokeFactory("Document", "doc3", title="Document 3")\n transaction.commit()\n- self.browser.open(self.portal_url + \'/sitemap\')\n+ self.browser.open(self.portal_url + "/sitemap")\n output = lxml.html.fromstring(self.browser.contents)\n sitemap = output.xpath("//ul[@id=\'portal-sitemap\']")[0].text_content()\n \n- self.assertTrue(\'Document 1\' in sitemap)\n- self.assertTrue(\'Document 2\' in sitemap)\n- self.assertTrue(\'Document 3\' in sitemap)\n+ self.assertTrue("Document 1" in sitemap)\n+ self.assertTrue("Document 2" in sitemap)\n+ self.assertTrue("Document 3" in sitemap)\n \n def test_sitemap_nested(self):\n- self.portal.invokeFactory(\'Folder\', \'folder1\', title=\'Folder 1\')\n- self.portal.invokeFactory(\'Document\', \'doc1\', title=\'Document 1\')\n- self.portal.invokeFactory(\'Folder\', \'folder2\', title=\'Folder 2\')\n- self.portal.folder1.invokeFactory(\n- \'Document\', \'doc12\', title=\'Document 12\')\n+ self.portal.invokeFactory("Folder", "folder1", title="Folder 1")\n+ self.portal.invokeFactory("Document", "doc1", title="Document 1")\n+ self.portal.invokeFactory("Folder", "folder2", title="Folder 2")\n+ self.portal.folder1.invokeFactory("Document", "doc12", title="Document 12")\n transaction.commit()\n \n- self.browser.open(self.portal_url + \'/sitemap\')\n+ self.browser.open(self.portal_url + "/sitemap")\n output = lxml.html.fromstring(self.browser.contents)\n sitemap = output.xpath("//ul[@id=\'portal-sitemap\']")[0].text_content()\n \n- self.assertTrue(\'Folder 1\' in sitemap)\n- self.assertTrue(\'Document 1\' in sitemap)\n- self.assertTrue(\'Folder 2\' in sitemap)\n- self.assertTrue(\'Document 12\' in sitemap)\n+ self.assertTrue("Folder 1" in sitemap)\n+ self.assertTrue("Document 1" in sitemap)\n+ self.assertTrue("Folder 2" in sitemap)\n+ self.assertTrue("Document 12" in sitemap)\ndiff --git a/Products/CMFPlone/tests/test_utils.py b/Products/CMFPlone/tests/test_utils.py\nindex 21031a5886..0fbbf60587 100644\n--- a/Products/CMFPlone/tests/test_utils.py\n+++ b/Products/CMFPlone/tests/test_utils.py\n@@ -13,52 +13,44 @@\n import unittest\n \n \n-SITE_LOGO_BASE64 = b\'filenameb64:cGl4ZWwucG5n;datab64:iVBORw0KGgoAAAANSUhEUgA\'\\\n- b\'AAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAA\'\\\n- b\'AAElFTkSuQmCC\'\n+SITE_LOGO_BASE64 = (\n+ b"filenameb64:cGl4ZWwucG5n;datab64:iVBORw0KGgoAAAANSUhEUgA"\n+ b"AAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAA"\n+ b"AAElFTkSuQmCC"\n+)\n \n \n class DefaultUtilsTests(unittest.TestCase):\n-\n def test_bodyfinder(self):\n from Products.CMFPlone.utils import bodyfinder\n \n- self.assertEqual(bodyfinder(FAUX_HTML_LEADING_TEXT),\n- \'\\n Not a lot here \\n \')\n- self.assertEqual(bodyfinder(SIMPLE_HTML),\n- \'\\n Not a lot here \\n \')\n- self.assertEqual(bodyfinder(SIMPLE_STRUCTUREDTEXT),\n- SIMPLE_STRUCTUREDTEXT)\n- self.assertEqual(bodyfinder(SIMPLE_XHTML),\n- \'\\n Not a lot here \\n \')\n- self.assertEqual(bodyfinder(STX_WITH_HTML),\n- \'Hello world, I am Bruce.
\')\n+ self.assertEqual(\n+ bodyfinder(FAUX_HTML_LEADING_TEXT), "\\n Not a lot here \\n "\n+ )\n+ self.assertEqual(bodyfinder(SIMPLE_HTML), "\\n Not a lot here \\n ")\n+ self.assertEqual(bodyfinder(SIMPLE_STRUCTUREDTEXT), SIMPLE_STRUCTUREDTEXT)\n+ self.assertEqual(bodyfinder(SIMPLE_XHTML), "\\n Not a lot here \\n ")\n+ self.assertEqual(bodyfinder(STX_WITH_HTML), "Hello world, I am Bruce.
")\n+\n \n class LogoTests(unittest.TestCase):\n-\n layer = PRODUCTS_CMFPLONE_INTEGRATION_TESTING\n \n def test_getSiteLogo_with_setting(self):\n from Products.CMFPlone.utils import getSiteLogo\n+\n registry = getUtility(IRegistry)\n- settings = registry.forInterface(ISiteSchema, prefix=\'plone\')\n+ settings = registry.forInterface(ISiteSchema, prefix="plone")\n settings.site_logo = SITE_LOGO_BASE64\n logo_url, logo_type = getSiteLogo(include_type=True)\n \n- self.assertTrue(\n- \'http://nohost/plone/@@site-logo/pixel.png\'\n- in logo_url)\n+ self.assertTrue("http://nohost/plone/@@site-logo/pixel.png" in logo_url)\n \n- self.assertEqual(\n- "image/png", logo_type\n- )\n+ self.assertEqual("image/png", logo_type)\n \n def test_getSiteLogo_with_no_setting(self):\n from Products.CMFPlone.utils import getSiteLogo\n+\n logo_url, logo_type = getSiteLogo(include_type=True)\n- self.assertTrue(\n- \'http://nohost/plone/++resource++plone-logo.svg\'\n- in logo_url)\n- self.assertEqual(\n- "image/svg+xml", logo_type\n- )\n+ self.assertTrue("http://nohost/plone/++resource++plone-logo.svg" in logo_url)\n+ self.assertEqual("image/svg+xml", logo_type)\ndiff --git a/Products/CMFPlone/tests/test_z3c_form_widgets.py b/Products/CMFPlone/tests/test_z3c_form_widgets.py\nindex 0e98131c04..6510a8dbd4 100644\n--- a/Products/CMFPlone/tests/test_z3c_form_widgets.py\n+++ b/Products/CMFPlone/tests/test_z3c_form_widgets.py\n@@ -16,7 +16,7 @@\n \n \n class FakeForm:\n- method = \'post\'\n+ method = "post"\n ignoreRequest = False\n \n \n@@ -37,58 +37,53 @@ def getTermByToken(self, token):\n return DummyTerms()\n \n def test_regression(self):\n- request = self.layer[\'request\']\n+ request = self.layer["request"]\n for Widget in self._widgets_to_test:\n wi = Widget(request)\n- wi.name = \'foo\'\n- request.REQUEST_METHOD = \'POST\'\n- request.form.update({\n- \'foo\': \'bar\'\n- })\n+ wi.name = "foo"\n+ request.REQUEST_METHOD = "POST"\n+ request.form.update({"foo": "bar"})\n wi.form = FakeForm()\n self.assertEqual(wi.ignoreRequest, False)\n # The SequenceWidget needs terms. It will have terms=None,\n # where the others have no terms attribute.\n- if getattr(wi, \'terms\', _marker) is None:\n+ if getattr(wi, "terms", _marker) is None:\n wi.terms = self._terms()\n wi.update()\n self.assertEqual(wi.ignoreRequest, False)\n \n def test_only_get_data_from_valid_request_method(self):\n- request = self.layer[\'request\']\n+ request = self.layer["request"]\n for Widget in self._widgets_to_test:\n wi = Widget(request)\n- wi.name = \'foobar\'\n- request.REQUEST_METHOD = \'GET\'\n- request.form.update({\n- \'foobar\': self._attack\n- })\n+ wi.name = "foobar"\n+ request.REQUEST_METHOD = "GET"\n+ request.form.update({"foobar": self._attack})\n wi.form = FakeForm()\n self.assertEqual(wi.ignoreRequest, False)\n # The SequenceWidget needs terms. It will have terms=None,\n # where the others have no terms attribute.\n- if getattr(wi, \'terms\', _marker) is None:\n+ if getattr(wi, "terms", _marker) is None:\n wi.terms = self._terms()\n wi.update()\n self.assertEqual(wi.ignoreRequest, True)\n \n def test_explicitly_allow_data_from_invalid_request_method(self):\n- request = self.layer[\'request\']\n+ request = self.layer["request"]\n for Widget in self._widgets_to_test:\n wi = Widget(request)\n- wi.name = \'foobar\'\n- request.REQUEST_METHOD = \'GET\'\n- request.form.update({\n- \'foobar\': self._attack\n- })\n+ wi.name = "foobar"\n+ request.REQUEST_METHOD = "GET"\n+ request.form.update({"foobar": self._attack})\n wi.form = FakeForm()\n # Set attribute on form to explicitly allow prefill.\n from Products.CMFPlone.patches.z3c_form import ALLOW_PREFILL\n+\n setattr(wi.form, ALLOW_PREFILL, True)\n self.assertEqual(wi.ignoreRequest, False)\n # The SequenceWidget needs terms. It will have terms=None,\n # where the others have no terms attribute.\n- if getattr(wi, \'terms\', _marker) is None:\n+ if getattr(wi, "terms", _marker) is None:\n wi.terms = self._terms()\n wi.update()\n self.assertEqual(wi.ignoreRequest, False)\n@@ -96,21 +91,19 @@ def test_explicitly_allow_data_from_invalid_request_method(self):\n def test_only_get_data_from_valid_referrer(self):\n # this handles the use case where hijacker gets user to click on\n # button that submits to plone site\n- request = self.layer[\'request\']\n+ request = self.layer["request"]\n \n for Widget in self._widgets_to_test:\n wi = Widget(request)\n- wi.name = \'foobar\'\n- request.REQUEST_METHOD = \'POST\'\n- request.form.update({\n- \'foobar\': self._attack\n- })\n- request.environ[\'HTTP_REFERER\'] = \'http://attacker.com\'\n+ wi.name = "foobar"\n+ request.REQUEST_METHOD = "POST"\n+ request.form.update({"foobar": self._attack})\n+ request.environ["HTTP_REFERER"] = "http://attacker.com"\n wi.form = FakeForm()\n self.assertEqual(wi.ignoreRequest, False)\n # The SequenceWidget needs terms. It will have terms=None,\n # where the others have no terms attribute.\n- if getattr(wi, \'terms\', _marker) is None:\n+ if getattr(wi, "terms", _marker) is None:\n wi.terms = self._terms()\n wi.update()\n self.assertEqual(wi.ignoreRequest, True)\ndiff --git a/Products/CMFPlone/tests/test_zmi.py b/Products/CMFPlone/tests/test_zmi.py\nindex 01d7f90787..21cb973828 100644\n--- a/Products/CMFPlone/tests/test_zmi.py\n+++ b/Products/CMFPlone/tests/test_zmi.py\n@@ -8,210 +8,208 @@\n \n \n class ZMITests(unittest.TestCase):\n- """Basic tests of ZMI management screens\n- """\n+ """Basic tests of ZMI management screens"""\n \n layer = PLONE_APP_CONTENTTYPES_INTEGRATION_TESTING\n \n def setUp(self):\n- self.portal = self.layer[\'portal\']\n- setRoles(self.portal, TEST_USER_ID, [\'Manager\'])\n+ self.portal = self.layer["portal"]\n+ setRoles(self.portal, TEST_USER_ID, ["Manager"])\n \n def test_manage(self):\n- url = \'manage\'\n+ url = "manage"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_manage_main(self):\n- url = \'manage_main\'\n+ url = "manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_manage_components(self):\n- url = \'manage_components\'\n+ url = "manage_components"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_manage_propertiesForm(self):\n- url = \'manage_propertiesForm\'\n+ url = "manage_propertiesForm"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_manage_owner(self):\n- url = \'manage_owner\'\n+ url = "manage_owner"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_manage_findForm(self):\n- url = \'manage_findForm\'\n+ url = "manage_findForm"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_acl_users(self):\n- url = \'acl_users/manage_main\'\n+ url = "acl_users/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_caching_policy_manager(self):\n- url = \'caching_policy_manager/manage_cachingPolicies\'\n+ url = "caching_policy_manager/manage_cachingPolicies"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_content_type_registry(self):\n- url = \'content_type_registry/manage_predicates\'\n+ url = "content_type_registry/manage_predicates"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_error_log(self):\n- url = \'error_log/manage_main\'\n+ url = "error_log/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_HTTPCache(self):\n- url = \'HTTPCache/manage_main\'\n+ url = "HTTPCache/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_MailHost(self):\n- url = \'MailHost/manage_main\'\n+ url = "MailHost/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_mimetypes_registry(self):\n- url = \'mimetypes_registry/manage_main\'\n+ url = "mimetypes_registry/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_actions(self):\n- url = \'portal_actions/manage_main\'\n+ url = "portal_actions/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_catalog(self):\n- url = \'portal_catalog/manage_main\'\n+ url = "portal_catalog/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_diff(self):\n- url = \'portal_diff/manage_difftypes\'\n+ url = "portal_diff/manage_difftypes"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_historiesstorage(self):\n- url = \'portal_historiesstorage/storageStatistics\'\n+ url = "portal_historiesstorage/storageStatistics"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_historyidhandler(self):\n- url = \'portal_historyidhandler/manage_queryObject\'\n+ url = "portal_historyidhandler/manage_queryObject"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_memberdata(self):\n- url = \'portal_memberdata/manage_overview\'\n+ url = "portal_memberdata/manage_overview"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_membership(self):\n- url = \'portal_membership/manage_mapRoles\'\n+ url = "portal_membership/manage_mapRoles"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_modifier(self):\n- url = \'portal_modifier/manage_main\'\n+ url = "portal_modifier/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_properties(self):\n- url = \'portal_properties/manage_main\'\n+ url = "portal_properties/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_purgepolicy(self):\n- url = \'portal_purgepolicy/manage_propertiesForm\'\n+ url = "portal_purgepolicy/manage_propertiesForm"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_referencefactories(self):\n- url = \'portal_referencefactories/manage_main\'\n+ url = "portal_referencefactories/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_registration(self):\n- url = \'portal_registration/manage_overview\'\n+ url = "portal_registration/manage_overview"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_repository(self):\n- url = \'portal_repository/manage_owner\'\n+ url = "portal_repository/manage_owner"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_resources(self):\n- url = \'portal_resources/manage_main\'\n+ url = "portal_resources/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_setup(self):\n- url = \'portal_setup/manage_main\'\n+ url = "portal_setup/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_skins(self):\n- url = \'portal_skins/manage_main\'\n+ url = "portal_skins/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_transforms(self):\n- url = \'portal_transforms/manage_main\'\n+ url = "portal_transforms/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_types(self):\n- url = \'portal_types/manage_main\'\n+ url = "portal_types/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_uidannotation(self):\n- url = \'portal_uidannotation/manage_propertiesForm\'\n+ url = "portal_uidannotation/manage_propertiesForm"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_uidhandler(self):\n- url = \'portal_uidhandler/manage_queryObject\'\n+ url = "portal_uidhandler/manage_queryObject"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_view_customizations(self):\n- url = \'portal_view_customizations/registrations.html\'\n+ url = "portal_view_customizations/registrations.html"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_portal_workflow(self):\n- url = \'portal_workflow/manage_main\'\n+ url = "portal_workflow/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_RAMCache(self):\n- url = \'RAMCache/manage_main\'\n+ url = "RAMCache/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_ResourceRegistryCache(self):\n- url = \'ResourceRegistryCache/manage_main\'\n+ url = "ResourceRegistryCache/manage_main"\n view = self.portal.restrictedTraverse(url)\n- self.assertTrue(view(), msg=f\'{url} is broken\')\n+ self.assertTrue(view(), msg=f"{url} is broken")\n \n def test_manage_access(self):\n- """manage_access cannot be travesed to directly\n- """\n- view = getattr(self.portal, \'_normal_manage_access\')\n- self.assertTrue(view(), msg=\'manage_access is broken\')\n+ """manage_access cannot be travesed to directly"""\n+ view = getattr(self.portal, "_normal_manage_access")\n+ self.assertTrue(view(), msg="manage_access is broken")\n \n def test_portal_controlpanel(self):\n # portal_controlpanel/manage_editActionsForm\n- controlpanel = self.portal.restrictedTraverse(\'portal_controlpanel\')\n+ controlpanel = self.portal.restrictedTraverse("portal_controlpanel")\n view = controlpanel._actions_form\n self.assertTrue(\n- view(),\n- msg=\'portal_controlpanel/manage_editActionsForm is broken\')\n+ view(), msg="portal_controlpanel/manage_editActionsForm is broken"\n+ )\ndiff --git a/Products/CMFPlone/tests/utils.py b/Products/CMFPlone/tests/utils.py\nindex ef857ca3fe..2adab39292 100644\n--- a/Products/CMFPlone/tests/utils.py\n+++ b/Products/CMFPlone/tests/utils.py\n@@ -9,7 +9,7 @@\n VALID_CSS_ID = re.compile("[A-Za-z_@][A-Za-z0-9_@-]*")\n \n \n-def folder_position(context, position=\'\', id=None, delta=1, reverse=None):\n+def folder_position(context, position="", id=None, delta=1, reverse=None):\n """\n XXX Why is this here you ask?\n \n@@ -19,24 +19,23 @@ def folder_position(context, position=\'\', id=None, delta=1, reverse=None):\n """\n \n position = position.lower()\n- if position == \'up\':\n+ if position == "up":\n context.moveObjectsUp(id, delta=delta)\n- elif position == \'down\':\n+ elif position == "down":\n context.moveObjectsDown(id, delta=delta)\n- elif position == \'top\':\n+ elif position == "top":\n context.moveObjectsToTop(id)\n- elif position == \'bottom\':\n+ elif position == "bottom":\n context.moveObjectsToBottom(id)\n # order folder by field\n # id in this case is the field\n- elif position == \'ordered\':\n+ elif position == "ordered":\n context.orderObjects(id, reverse)\n context.plone_utils.reindexOnReorder(context)\n \n \n class MockMailHost(MailBase):\n- """A MailHost that collects messages instead of sending them.\n- """\n+ """A MailHost that collects messages instead of sending them."""\n \n def __init__(self, id):\n self.reset()\n@@ -45,27 +44,29 @@ def reset(self):\n self.messages = PersistentList()\n \n def _send(self, mfrom, mto, messageText, immediate=False):\n- """ Send the message """\n+ """Send the message"""\n self.messages.append(messageText)\n \n- def send(self,\n- messageText,\n- mto=None,\n- mfrom=None,\n- subject=None,\n- encode=None,\n- immediate=False,\n- charset=None,\n- msg_type=None):\n+ def send(\n+ self,\n+ messageText,\n+ mto=None,\n+ mfrom=None,\n+ subject=None,\n+ encode=None,\n+ immediate=False,\n+ charset=None,\n+ msg_type=None,\n+ ):\n """send *messageText* modified by the other parameters.\n \n *messageText* can either be an ``email.message.Message``\n or a string.\n Note that Products.MailHost 4.10 had changes here.\n """\n- msg, mto, mfrom = _mungeHeaders(messageText, mto, mfrom,\n- subject, charset, msg_type,\n- encode)\n+ msg, mto, mfrom = _mungeHeaders(\n+ messageText, mto, mfrom, subject, charset, msg_type, encode\n+ )\n self.messages.append(msg)\n \n \ndiff --git a/Products/CMFPlone/unicodeconflictresolver.py b/Products/CMFPlone/unicodeconflictresolver.py\nindex 11cd35f4d5..e7151e7c93 100644\n--- a/Products/CMFPlone/unicodeconflictresolver.py\n+++ b/Products/CMFPlone/unicodeconflictresolver.py\n@@ -6,10 +6,11 @@\n @implementer(IUnicodeEncodingConflictResolver)\n class UTF8EncodingConflictResolver:\n """This resolver tries to decode a string from utf-8 and replaces it\n- otherwise but logs a warning.\n+ otherwise but logs a warning.\n """\n \n def resolve(self, context, text, expression):\n return _unicode_replace(text)\n \n+\n UTF8EncodingConflictResolver = UTF8EncodingConflictResolver()\ndiff --git a/Products/CMFPlone/utils.py b/Products/CMFPlone/utils.py\nindex e731e62532..9176f89c46 100644\n--- a/Products/CMFPlone/utils.py\n+++ b/Products/CMFPlone/utils.py\n@@ -62,19 +62,19 @@\n \n deprecated_import(\n "Import from plone.base.utils instead (will be removed in Plone 7)",\n- base_hasattr=\'plone.base.utils:base_hasattr\',\n- getEmptyTitle=\'plone.base.utils:get_empty_title\',\n- human_readable_size=\'plone.base.utils:human_readable_size\',\n- safeToInt=\'plone.base.utils:safe_int\',\n- safe_bytes=\'plone.base.utils:safe_bytes\',\n- safe_callable=\'plone.base.utils:safe_callable\',\n- safe_hasattr=\'plone.base.utils:safe_hasattr\',\n- safe_text=\'plone.base.utils:safe_text\',\n- get_installer=\'plone.base.utils:get_installer\',\n- get_top_request=\'plone.base.utils:get_top_request\',\n- get_top_site_from_url=\'plone.base.utils:get_top_site_from_url\',\n- pretty_title_or_id=\'plone.base.utils:pretty_title_or_id\',\n- _createObjectByType=\'plone.base.utils:unrestricted_construct_instance\',\n+ base_hasattr="plone.base.utils:base_hasattr",\n+ getEmptyTitle="plone.base.utils:get_empty_title",\n+ human_readable_size="plone.base.utils:human_readable_size",\n+ safeToInt="plone.base.utils:safe_int",\n+ safe_bytes="plone.base.utils:safe_bytes",\n+ safe_callable="plone.base.utils:safe_callable",\n+ safe_hasattr="plone.base.utils:safe_hasattr",\n+ safe_text="plone.base.utils:safe_text",\n+ get_installer="plone.base.utils:get_installer",\n+ get_top_request="plone.base.utils:get_top_request",\n+ get_top_site_from_url="plone.base.utils:get_top_site_from_url",\n+ pretty_title_or_id="plone.base.utils:pretty_title_or_id",\n+ _createObjectByType="plone.base.utils:unrestricted_construct_instance",\n )\n \n deprecated_import(\n@@ -84,44 +84,46 @@\n getQuality="plone.namedfile.utils:getQuality",\n )\n \n+\n @deprecate("Use plone.base.utils.safe_bytes instead (will be removed in Plone 7)")\n def safe_encode(*args, **kwargs):\n return base_utils.safe_bytes(*args, **kwargs)\n \n+\n @deprecate("Use plone.base.utils.safe_text instead (will be removed in Plone 7)")\n def safe_unicode(*args, **kwargs):\n return base_utils.safe_text(*args, **kwargs)\n \n+\n @deprecate("Use plone.base.utils.safe_text instead (will be removed in Plone 7)")\n-def safe_nativestring(value, encoding=\'utf-8\'):\n- """Convert a value to str in py2 and to text in py3\n- """\n+def safe_nativestring(value, encoding="utf-8"):\n+ """Convert a value to str in py2 and to text in py3"""\n if isinstance(value, bytes):\n value = base_utils.safe_text(value, encoding)\n return value\n \n \n security = ModuleSecurityInfo()\n-security.declarePrivate(\'deprecated\')\n-security.declarePrivate(\'abspath\')\n-security.declarePrivate(\'re\')\n-security.declarePrivate(\'OFS\')\n-security.declarePrivate(\'aq_get\')\n-security.declarePrivate(\'package_home\')\n-security.declarePrivate(\'ImageFile\')\n-security.declarePrivate(\'CMFCoreToolInit\')\n-security.declarePrivate(\'transaction\')\n-security.declarePrivate(\'zope\')\n+security.declarePrivate("deprecated")\n+security.declarePrivate("abspath")\n+security.declarePrivate("re")\n+security.declarePrivate("OFS")\n+security.declarePrivate("aq_get")\n+security.declarePrivate("package_home")\n+security.declarePrivate("ImageFile")\n+security.declarePrivate("CMFCoreToolInit")\n+security.declarePrivate("transaction")\n+security.declarePrivate("zope")\n \n # Canonical way to get at CMFPlone directory\n PACKAGE_HOME = package_home(globals())\n-security.declarePrivate(\'PACKAGE_HOME\')\n-WWW_DIR = join(PACKAGE_HOME, \'www\')\n-security.declarePrivate(\'WWW_DIR\')\n+security.declarePrivate("PACKAGE_HOME")\n+WWW_DIR = join(PACKAGE_HOME, "www")\n+security.declarePrivate("WWW_DIR")\n \n # image-scaling\n QUALITY_DEFAULT = 88\n-pattern = re.compile(r\'^(.*)\\s+(\\d+)\\s*:\\s*(\\d+)$\')\n+pattern = re.compile(r"^(.*)\\s+(\\d+)\\s*:\\s*(\\d+)$")\n \n _marker = []\n \n@@ -144,18 +146,17 @@ def parent(obj):\n \n \n def createBreadCrumbs(context, request):\n- view = getMultiAdapter((context, request), name=\'breadcrumbs_view\')\n+ view = getMultiAdapter((context, request), name="breadcrumbs_view")\n return view.breadcrumbs()\n \n \n def createSiteMap(context, request, sitemap=False):\n- view = getMultiAdapter((context, request), name=\'sitemap_builder_view\')\n+ view = getMultiAdapter((context, request), name="sitemap_builder_view")\n return view.siteMap()\n \n \n-\n def isExpired(content):\n- """ Find out if the object is expired (copied from skin script) """\n+ """Find out if the object is expired (copied from skin script)"""\n \n expiry = None\n \n@@ -167,11 +168,11 @@ def isExpired(content):\n # convert to a DateTime\n \n # Try DC accessor first\n- if base_hasattr(content, \'ExpirationDate\'):\n+ if base_hasattr(content, "ExpirationDate"):\n expiry = content.ExpirationDate\n \n # Try the direct way\n- if not expiry and base_hasattr(content, \'expires\'):\n+ if not expiry and base_hasattr(content, "expires"):\n expiry = content.expires\n \n # See if we have a callable\n@@ -179,7 +180,7 @@ def isExpired(content):\n expiry = expiry()\n \n # Convert to DateTime if necessary, ExpirationDate may return \'None\'\n- if expiry and expiry != \'None\' and isinstance(expiry, str):\n+ if expiry and expiry != "None" and isinstance(expiry, str):\n expiry = DateTime(expiry)\n \n if isinstance(expiry, DateTime) and expiry.isPast():\n@@ -189,7 +190,7 @@ def isExpired(content):\n \n def typesToList(context):\n registry = getUtility(IRegistry)\n- return registry.get(\'plone.displayed_types\', ())\n+ return registry.get("plone.displayed_types", ())\n \n \n def normalizeString(text, context=None, encoding=None):\n@@ -202,6 +203,7 @@ class RealIndexIterator:\n """The \'real\' version of the IndexIterator class, that\'s actually\n used to generate unique indexes.\n """\n+\n __allow_access_to_unprotected_subobjects__ = 1\n \n def __init__(self, pos=0):\n@@ -218,14 +220,13 @@ def __next__(self):\n \n @security.private\n class ToolInit(CMFCoreToolInit):\n-\n def getProductContext(self, context):\n- name = \'_ProductContext__prod\'\n- return getattr(context, name, getattr(context, \'__prod\', None))\n+ name = "_ProductContext__prod"\n+ return getattr(context, name, getattr(context, "__prod", None))\n \n def getPack(self, context):\n- name = \'_ProductContext__pack\'\n- return getattr(context, name, getattr(context, \'__pack__\', None))\n+ name = "_ProductContext__pack"\n+ return getattr(context, name, getattr(context, "__pack__", None))\n \n def getIcon(self, context, path):\n pack = self.getPack(context)\n@@ -243,9 +244,10 @@ def getIcon(self, context, path):\n except OSError:\n # if there is some problem loading the fancy image\n # from the tool then tell someone about it\n- log(\'The icon for the product: %s which was set to: %s, \'\n- \'was not found. Using the default.\' %\n- (self.product_name, icon_path))\n+ log(\n+ "The icon for the product: %s which was set to: %s, "\n+ "was not found. Using the default." % (self.product_name, icon_path)\n+ )\n return icon\n \n def initialize(self, context):\n@@ -253,7 +255,7 @@ def initialize(self, context):\n CMFCoreToolInit.initialize(self, context)\n for tool in self.tools:\n # Get the icon path from the tool\n- path = getattr(tool, \'toolicon\', None)\n+ path = getattr(tool, "toolicon", None)\n if path is not None:\n pc = self.getProductContext(context)\n if pc is not None:\n@@ -264,7 +266,7 @@ def initialize(self, context):\n # Icon was not found\n return\n icon.__roles__ = None\n- tool.icon = f\'misc_/{self.product_name}/{name}\'\n+ tool.icon = f"misc_/{self.product_name}/{name}"\n misc = OFS.misc_.misc_\n Misc = OFS.misc_.Misc_\n if not hasattr(misc, pid):\n@@ -272,28 +274,28 @@ def initialize(self, context):\n getattr(misc, pid)[name] = icon\n \n \n-release_levels = (\'alpha\', \'beta\', \'candidate\', \'final\')\n-rl_abbr = {\'a\': \'alpha\', \'b\': \'beta\', \'rc\': \'candidate\'}\n+release_levels = ("alpha", "beta", "candidate", "final")\n+rl_abbr = {"a": "alpha", "b": "beta", "rc": "candidate"}\n \n \n def versionTupleFromString(v_str):\n """Returns version tuple from passed in version string\n \n- >>> versionTupleFromString(\'1.2.3\')\n- (1, 2, 3, \'final\', 0)\n+ >>> versionTupleFromString(\'1.2.3\')\n+ (1, 2, 3, \'final\', 0)\n \n- >>> versionTupleFromString(\'2.1-final1 (SVN)\')\n- (2, 1, 0, \'final\', 1)\n+ >>> versionTupleFromString(\'2.1-final1 (SVN)\')\n+ (2, 1, 0, \'final\', 1)\n \n- >>> versionTupleFromString(\'3-beta\')\n- (3, 0, 0, \'beta\', 0)\n+ >>> versionTupleFromString(\'3-beta\')\n+ (3, 0, 0, \'beta\', 0)\n \n- >>> versionTupleFromString(\'2.0a3\')\n- (2, 0, 0, \'alpha\', 3)\n+ >>> versionTupleFromString(\'2.0a3\')\n+ (2, 0, 0, \'alpha\', 3)\n \n- >>> versionTupleFromString(\'foo\') is None\n- True\n- """\n+ >>> versionTupleFromString(\'foo\') is None\n+ True\n+ """\n regex_str = r"(^\\d+)[.]?(\\d*)[.]?(\\d*)[- ]?(alpha|beta|candidate|final|a|b|rc)?(\\d*)" # noqa\n v_regex = re.compile(regex_str)\n match = v_regex.match(v_str)\n@@ -304,7 +306,7 @@ def versionTupleFromString(v_str):\n for i in (0, 1, 2, 4):\n groups[i] = base_utils.safe_int(groups[i])\n if groups[3] is None:\n- groups[3] = \'final\'\n+ groups[3] = "final"\n elif groups[3] in rl_abbr.keys():\n groups[3] = rl_abbr[groups[3]]\n v_tpl = tuple(groups)\n@@ -313,7 +315,7 @@ def versionTupleFromString(v_str):\n \n def getFSVersionTuple():\n """Returns Products.CMFPlone version tuple"""\n- version = pkg_resources.get_distribution(\'Products.CMFPlone\').version\n+ version = pkg_resources.get_distribution("Products.CMFPlone").version\n return versionTupleFromString(version)\n \n \n@@ -321,7 +323,7 @@ def transaction_note(note):\n """Write human legible note"""\n T = transaction.get()\n if (len(T.description) + len(note)) >= 65533:\n- log(\'Transaction note too large omitting %s\' % str(note))\n+ log("Transaction note too large omitting %s" % str(note))\n else:\n T.note(base_utils.safe_text(note))\n \n@@ -378,7 +380,7 @@ def webdav_enabled(obj, container):\n # a dependency.\n \n \n-security.declarePrivate(\'sys\')\n+security.declarePrivate("sys")\n \n \n def _unrestricted_rename(container, id, new_id):\n@@ -394,20 +396,22 @@ def _unrestricted_rename(container, id, new_id):\n try:\n container._checkId(new_id)\n except:\n- raise CopyError(MessageDialog(\n- title=\'Invalid Id\',\n- message=sys.exc_info()[1],\n- action=\'manage_main\'))\n+ raise CopyError(\n+ MessageDialog(\n+ title="Invalid Id", message=sys.exc_info()[1], action="manage_main"\n+ )\n+ )\n ob = container._getOb(id)\n if not ob.cb_isMoveable():\n- raise CopyError(f\'Not Supported {escape(id)}\')\n+ raise CopyError(f"Not Supported {escape(id)}")\n try:\n ob._notifyOfCopyTo(container, op=1)\n except:\n- raise CopyError(MessageDialog(\n- title=\'Rename Error\',\n- message=sys.exc_info()[1],\n- action=\'manage_main\'))\n+ raise CopyError(\n+ MessageDialog(\n+ title="Rename Error", message=sys.exc_info()[1], action="manage_main"\n+ )\n+ )\n container._delObject(id)\n ob = aq_base(ob)\n ob._setId(new_id)\n@@ -423,7 +427,7 @@ def _unrestricted_rename(container, id, new_id):\n \n # Copied \'_getSecurity\' from Archetypes.utils to avoid a dependency.\n \n-security.declarePrivate(\'ClassSecurityInfo\')\n+security.declarePrivate("ClassSecurityInfo")\n \n \n def _getSecurity(klass, create=True):\n@@ -433,7 +437,7 @@ def _getSecurity(klass, create=True):\n info = vars(klass)\n security = None\n for k, v in info.items():\n- if hasattr(v, \'__security_info__\'):\n+ if hasattr(v, "__security_info__"):\n security = v\n break\n # Didn\'t found a ClassSecurityInfo object\n@@ -444,7 +448,7 @@ def _getSecurity(klass, create=True):\n # could theoretically lead to name clashes, and doesn\'t matter for\n # zope 2 anyway.\n security = ClassSecurityInfo()\n- setattr(klass, \'__security__\', security)\n+ setattr(klass, "__security__", security)\n return security\n \n \n@@ -456,37 +460,37 @@ def set_own_login_name(member, loginname):\n bit weird then. Historical accident.\n """\n portal = getSite()\n- pas = getToolByName(portal, \'acl_users\')\n- mt = getToolByName(portal, \'portal_membership\')\n+ pas = getToolByName(portal, "acl_users")\n+ mt = getToolByName(portal, "portal_membership")\n if member.getId() == mt.getAuthenticatedMember().getId():\n pas.updateOwnLoginName(loginname)\n return\n secman = getSecurityManager()\n if not secman.checkPermission(ManageUsers, member):\n- raise Unauthorized(\'You can only change your OWN login name.\')\n+ raise Unauthorized("You can only change your OWN login name.")\n pas.updateLoginName(member.getId(), loginname)\n \n \n def ajax_load_url(url):\n- if url and \'ajax_load\' not in url:\n- sep = \'?\' in url and \'&\' or \'?\' # url parameter seperator\n- url = f\'{url}{sep}ajax_load=1\'\n+ if url and "ajax_load" not in url:\n+ sep = "?" in url and "&" or "?" # url parameter seperator\n+ url = f"{url}{sep}ajax_load=1"\n return url\n \n \n def bodyfinder(text):\n- """ Return body or unchanged text if no body tags found.\n+ """Return body or unchanged text if no body tags found.\n \n Always use html_headcheck() first.\n """\n lowertext = text.lower()\n- bodystart = lowertext.find(\'\', bodystart) + 1\n+ bodystart = lowertext.find(">", bodystart) + 1\n if bodystart == 0:\n return text\n- bodyend = lowertext.rfind(\'\', bodystart)\n+ bodyend = lowertext.rfind("