From e9996654470f1a3393d668ca52e2a239ab031ff2 Mon Sep 17 00:00:00 2001 From: mauritsvanrees Date: Thu, 23 Jan 2025 11:01:02 +0100 Subject: [PATCH] [fc] Repository: plone.app.event Branch: refs/heads/master Date: 2025-01-23T00:00:20+01:00 Author: Maurits van Rees (mauritsvanrees) Commit: https://github.com/plone/plone.app.event/commit/e3f3e397135cb40f2409b84df4fd8d3a5335a766 Support `icalendar` 6 by forcing it to use its `pytz` timezone implementation. The new `zoneinfo` support in `icalendar` 6 does not work for us yet, giving indexing problems. So we call `icalendar.use_pytz` at startup. If this fails, we must be using an older version where `pytz` is the only option anyway, so we ignore this. Files changed: A news/6.bugfix M plone/app/event/__init__.py Repository: plone.app.event Branch: refs/heads/master Date: 2025-01-23T11:01:02+01:00 Author: Maurits van Rees (mauritsvanrees) Commit: https://github.com/plone/plone.app.event/commit/7985b0fd7a9f8a395fc4a9658548ce11b246520f Merge pull request #419 from plone/icalendar-6-pytz Support icalendar 6 by forcing it to use pytz Files changed: A news/6.bugfix M plone/app/event/__init__.py --- last_commit.txt | 66 +++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 44 deletions(-) diff --git a/last_commit.txt b/last_commit.txt index 0a07a44f6e..6fd1fd5326 100644 --- a/last_commit.txt +++ b/last_commit.txt @@ -1,60 +1,38 @@ -Repository: plone.volto +Repository: plone.app.event -Branch: refs/heads/main -Date: 2025-01-20T22:33:35+01:00 +Branch: refs/heads/master +Date: 2025-01-23T00:00:20+01:00 Author: Maurits van Rees (mauritsvanrees) -Commit: https://github.com/plone/plone.volto/commit/31a419d8f00a7604e2ae753d8dc588bd7f455686 +Commit: https://github.com/plone/plone.app.event/commit/e3f3e397135cb40f2409b84df4fd8d3a5335a766 -Fix DeprecationWarnings. +Support `icalendar` 6 by forcing it to use its `pytz` timezone implementation. -Files changed: -A news/4090.bugfix -M src/plone/volto/behaviors/preview_link.py -M src/plone/volto/browser/breadcrumbs.py -M src/plone/volto/browser/navigation.py -M src/plone/volto/coresandbox/example.py -M src/plone/volto/profiles/default/registry.xml -M src/plone/volto/testing.py - -b'diff --git a/news/4090.bugfix b/news/4090.bugfix\nnew file mode 100644\nindex 0000000..8528aef\n--- /dev/null\n+++ b/news/4090.bugfix\n@@ -0,0 +1 @@\n+Fix DeprecationWarnings. [maurits]\ndiff --git a/src/plone/volto/behaviors/preview_link.py b/src/plone/volto/behaviors/preview_link.py\nindex 060d03f..d207c13 100644\n--- a/src/plone/volto/behaviors/preview_link.py\n+++ b/src/plone/volto/behaviors/preview_link.py\n@@ -1,5 +1,5 @@\n from plone import api\n-from plone.app.z3cform.widget import RelatedItemsFieldWidget\n+from plone.app.z3cform.widgets.relateditems import RelatedItemsFieldWidget\n from plone.autoform import directives\n from plone.autoform.interfaces import IFormFieldProvider\n from plone.base.interfaces import IImageScalesFieldAdapter\ndiff --git a/src/plone/volto/browser/breadcrumbs.py b/src/plone/volto/browser/breadcrumbs.py\nindex 9799865..690b5a7 100644\n--- a/src/plone/volto/browser/breadcrumbs.py\n+++ b/src/plone/volto/browser/breadcrumbs.py\n@@ -1,10 +1,10 @@\n from Acquisition import aq_base\n from Acquisition import aq_inner\n from Acquisition import aq_parent\n-from plone.app.layout.navigation.interfaces import INavigationRoot\n-from plone.app.layout.navigation.root import getNavigationRoot\n from plone.base.defaultpage import check_default_page_via_view\n from plone.base.interfaces import IHideFromBreadcrumbs\n+from plone.base.interfaces import INavigationRoot\n+from plone.base.navigationroot import get_navigation_root\n from plone.base.utils import pretty_title_or_id\n from Products.CMFPlone.browser.interfaces import INavigationBreadcrumbs\n from Products.CMFPlone.browser.navigation import get_view_url\n@@ -42,7 +42,7 @@ def breadcrumbs(self):\n if IHideFromBreadcrumbs.providedBy(context):\n return base\n \n- rootPath = getNavigationRoot(context)\n+ rootPath = get_navigation_root(context)\n itemPath = "/".join(context.getPhysicalPath())\n \n # don\'t show default pages in breadcrumbs or pages above the navigation\ndiff --git a/src/plone/volto/browser/navigation.py b/src/plone/volto/browser/navigation.py\nindex 66941a8..a0c6bf8 100644\n--- a/src/plone/volto/browser/navigation.py\n+++ b/src/plone/volto/browser/navigation.py\n@@ -1,8 +1,8 @@\n from Acquisition import aq_inner\n from Missing import Missing\n-from plone.app.layout.navigation.root import getNavigationRoot\n from plone.base import utils\n from plone.base.interfaces import INavigationSchema\n+from plone.base.navigationroot import get_navigation_root\n from plone.registry.interfaces import IRegistry\n from Products.CMFCore.utils import getToolByName\n from Products.CMFPlone.browser.interfaces import INavigationTabs\n@@ -28,7 +28,7 @@ def _getNavQuery(self):\n else:\n query = {}\n \n- query["path"] = {"query": getNavigationRoot(self.context), "depth": 1}\n+ query["path"] = {"query": get_navigation_root(self.context), "depth": 1}\n query["portal_type"] = [t for t in navigation_settings.displayed_types]\n query["sort_on"] = navigation_settings.sort_tabs_on\n if navigation_settings.sort_tabs_reversed:\ndiff --git a/src/plone/volto/coresandbox/example.py b/src/plone/volto/coresandbox/example.py\nindex 535ac7e..675b00f 100644\n--- a/src/plone/volto/coresandbox/example.py\n+++ b/src/plone/volto/coresandbox/example.py\n@@ -1,9 +1,9 @@\n from plone.app.textfield import RichText\n from plone.app.vocabularies.catalog import CatalogSource\n from plone.app.vocabularies.catalog import StaticCatalogVocabulary\n-from plone.app.z3cform.widget import AjaxSelectFieldWidget\n-from plone.app.z3cform.widget import RelatedItemsFieldWidget\n-from plone.app.z3cform.widget import SelectFieldWidget\n+from plone.app.z3cform.widgets.relateditems import RelatedItemsFieldWidget\n+from plone.app.z3cform.widgets.select import AjaxSelectFieldWidget\n+from plone.app.z3cform.widgets.select import Select2FieldWidget\n from plone.autoform import directives\n from plone.dexterity.content import Container\n from plone.namedfile.field import NamedBlobFile\n@@ -183,7 +183,7 @@ class IExample(model.Schema):\n required=False,\n )\n \n- directives.widget(choice_field_select=SelectFieldWidget)\n+ directives.widget(choice_field_select=Select2FieldWidget)\n choice_field_select = schema.Choice(\n title="Choicefield with select2 widget",\n description="zope.schema.Choice",\n@@ -214,7 +214,7 @@ class IExample(model.Schema):\n default=[],\n )\n \n- directives.widget(list_field_select=SelectFieldWidget)\n+ directives.widget(list_field_select=Select2FieldWidget)\n list_field_select = schema.List(\n title="List field with select widget",\n description="zope.schema.List",\n@@ -437,7 +437,7 @@ class IExample(model.Schema):\n )\n directives.widget(\n "relationchoice_field_select",\n- SelectFieldWidget,\n+ Select2FieldWidget,\n )\n \n relationchoice_field_radio = RelationChoice(\n@@ -465,7 +465,7 @@ class IExample(model.Schema):\n )\n directives.widget(\n "relationlist_field_select",\n- SelectFieldWidget,\n+ Select2FieldWidget,\n pattern_options={\n "closeOnSelect": False, # Select2 option to leave dropdown open for multiple selection\n },\n@@ -620,7 +620,7 @@ class IExample(model.Schema):\n )\n directives.widget(\n "uuid_choice_field_select",\n- SelectFieldWidget,\n+ Select2FieldWidget,\n )\n \n uuid_choice_field_radio = schema.Choice(\n@@ -648,7 +648,7 @@ class IExample(model.Schema):\n )\n directives.widget(\n "uuid_list_field_select",\n- SelectFieldWidget,\n+ Select2FieldWidget,\n pattern_options={\n "closeOnSelect": False, # Select2 option to leave dropdown open for multiple selection\n },\ndiff --git a/src/plone/volto/profiles/default/registry.xml b/src/plone/volto/profiles/default/registry.xml\nindex aa8d206..1a97e36 100644\n--- a/src/plone/volto/profiles/default/registry.xml\n+++ b/src/plone/volto/profiles/default/registry.xml\n@@ -2,7 +2,7 @@\n \n \n \n False\n@@ -14,7 +14,7 @@\n \n \n \n@@ -23,7 +23,7 @@\n \n \n \ndiff --git a/src/plone/volto/testing.py b/src/plone/volto/testing.py\nindex d5f4304..2fb6677 100644\n--- a/src/plone/volto/testing.py\n+++ b/src/plone/volto/testing.py\n@@ -7,7 +7,7 @@\n from plone.app.testing import setRoles\n from plone.app.testing import TEST_USER_ID\n from plone.distribution.testing.layer import PloneDistributionFixture\n-from plone.testing import z2\n+from plone.testing import zope\n \n import plone.app.caching # noQA\n import plone.app.discussion # noQA\n@@ -62,13 +62,17 @@ class PloneVoltoCoreLayer(PloneSandboxLayer):\n \n \n PLONE_VOLTO_CORE_FUNCTIONAL_TESTING = FunctionalTesting(\n- bases=(PLONE_VOLTO_CORE_FIXTURE, z2.ZSERVER_FIXTURE),\n+ bases=(PLONE_VOLTO_CORE_FIXTURE, zope.WSGI_SERVER_FIXTURE),\n name="PloneVoltoCoreLayer:FunctionalTesting",\n )\n \n \n PLONE_VOLTO_CORE_ACCEPTANCE_TESTING = FunctionalTesting(\n- bases=(PLONE_VOLTO_CORE_FIXTURE, REMOTE_LIBRARY_BUNDLE_FIXTURE, z2.ZSERVER_FIXTURE),\n+ bases=(\n+ PLONE_VOLTO_CORE_FIXTURE,\n+ REMOTE_LIBRARY_BUNDLE_FIXTURE,\n+ zope.WSGI_SERVER_FIXTURE,\n+ ),\n name="PloneVoltoCoreLayer:AcceptanceTesting",\n )\n \n@@ -108,7 +112,7 @@ def setUpPloneSite(self, portal):\n \n \n PLONE_VOLTO_CORESANDBOX_FUNCTIONAL_TESTING = FunctionalTesting(\n- bases=(PLONE_VOLTO_CORESANDBOX_FIXTURE, z2.ZSERVER_FIXTURE),\n+ bases=(PLONE_VOLTO_CORESANDBOX_FIXTURE, zope.WSGI_SERVER_FIXTURE),\n name="PloneVoltoCoreSandboxLayer:FunctionalTesting",\n )\n \n@@ -117,7 +121,7 @@ def setUpPloneSite(self, portal):\n bases=(\n PLONE_VOLTO_CORESANDBOX_FIXTURE,\n REMOTE_LIBRARY_BUNDLE_FIXTURE,\n- z2.ZSERVER_FIXTURE,\n+ zope.WSGI_SERVER_FIXTURE,\n ),\n name="PloneVoltoCoreSandboxLayer:AcceptanceTesting",\n )\n@@ -144,6 +148,6 @@ def setUpPloneSite(self, portal):\n \n \n PLONE_VOLTO_MIGRATION_FUNCTIONAL_TESTING = FunctionalTesting(\n- bases=(PLONE_VOLTO_MIGRATION_FIXTURE, z2.ZSERVER_FIXTURE),\n+ bases=(PLONE_VOLTO_MIGRATION_FIXTURE, zope.WSGI_SERVER_FIXTURE),\n name="PloneVoltoMigrationLayer:FunctionalTesting",\n )\n' - -Repository: plone.volto - - -Branch: refs/heads/main -Date: 2025-01-22T10:41:22+01:00 -Author: Maurits van Rees (mauritsvanrees) -Commit: https://github.com/plone/plone.volto/commit/995899cddc04e4aac7dffc6c579866a9b91948df - -Merge branch 'main' into maurits-warnings +The new `zoneinfo` support in `icalendar` 6 does not work for us yet, giving indexing problems. +So we call `icalendar.use_pytz` at startup. +If this fails, we must be using an older version where `pytz` is the only option anyway, so we ignore this. Files changed: -A news/181.bugfix -M src/plone/volto/summary.py +A news/6.bugfix +M plone/app/event/__init__.py -b'diff --git a/news/181.bugfix b/news/181.bugfix\nnew file mode 100644\nindex 0000000..70193a8\n--- /dev/null\n+++ b/news/181.bugfix\n@@ -0,0 +1 @@\n+Add nav_title and head_title to the default summary serializer metadata fields. @davisagli\ndiff --git a/src/plone/volto/summary.py b/src/plone/volto/summary.py\nindex b2e5dda..0a71a45 100644\n--- a/src/plone/volto/summary.py\n+++ b/src/plone/volto/summary.py\n@@ -6,6 +6,8 @@\n class JSONSummarySerializerMetadata:\n def default_metadata_fields(self):\n return {\n+ "head_title",\n "image_field",\n "image_scales",\n+ "nav_title",\n }\n' +b'diff --git a/news/6.bugfix b/news/6.bugfix\nnew file mode 100644\nindex 00000000..b000847d\n--- /dev/null\n+++ b/news/6.bugfix\n@@ -0,0 +1,5 @@\n+Support ``icalendar`` 6 by forcing it to use its ``pytz`` timezone implementation.\n+The new ``zoneinfo`` support in ``icalendar`` 6 does not work for us yet, giving indexing problems.\n+So we call ``icalendar.use_pytz`` at startup.\n+If this fails, we must be using an older version where ``pytz`` is the only option anyway, so we ignore this.\n+[maurits]\ndiff --git a/plone/app/event/__init__.py b/plone/app/event/__init__.py\nindex bac87e2c..62ed906e 100644\n--- a/plone/app/event/__init__.py\n+++ b/plone/app/event/__init__.py\n@@ -1,10 +1,27 @@\n from AccessControl.Permission import addPermission\n from zope.i18nmessageid import MessageFactory\n \n+import icalendar\n+import logging\n \n+\n+logger = logging.getLogger(__name__)\n packageName = __name__\n _ = MessageFactory("plone")\n \n+# We are not yet ready to use the standard zoneinfo implementation\n+# introduced in icalendar 6. For starters, the tests fail when\n+# Products.DateRecurringIndex.index.index_object is called:\n+# SystemError: returned a result with an exception set\n+try:\n+ icalendar.use_pytz()\n+ logger.info("icalendar has been set up to use pytz instead of zoneinfo.")\n+except AttributeError:\n+ # If use_pytz does not exist, we either have an older icalender version\n+ # that only supports pytz anyway, or we have a newer version that no\n+ # longer supports it at all.\n+ pass\n+\n # BBB Permissions\n PORTAL_ADD_PERMISSION = "Add portal events" # CMFCalendar/ATCT permissions\n \n' -Repository: plone.volto +Repository: plone.app.event -Branch: refs/heads/main -Date: 2025-01-22T08:00:26-08:00 -Author: David Glick (davisagli) -Commit: https://github.com/plone/plone.volto/commit/17e796045e3efaf4753f0043788474a8b2303dfd +Branch: refs/heads/master +Date: 2025-01-23T11:01:02+01:00 +Author: Maurits van Rees (mauritsvanrees) +Commit: https://github.com/plone/plone.app.event/commit/7985b0fd7a9f8a395fc4a9658548ce11b246520f -Merge pull request #179 from plone/maurits-warnings +Merge pull request #419 from plone/icalendar-6-pytz -Fix DeprecationWarnings. +Support icalendar 6 by forcing it to use pytz Files changed: -A news/4090.bugfix -M src/plone/volto/behaviors/preview_link.py -M src/plone/volto/browser/breadcrumbs.py -M src/plone/volto/browser/navigation.py -M src/plone/volto/coresandbox/example.py -M src/plone/volto/profiles/default/registry.xml -M src/plone/volto/testing.py - -b'diff --git a/news/4090.bugfix b/news/4090.bugfix\nnew file mode 100644\nindex 0000000..8528aef\n--- /dev/null\n+++ b/news/4090.bugfix\n@@ -0,0 +1 @@\n+Fix DeprecationWarnings. [maurits]\ndiff --git a/src/plone/volto/behaviors/preview_link.py b/src/plone/volto/behaviors/preview_link.py\nindex 060d03f..d207c13 100644\n--- a/src/plone/volto/behaviors/preview_link.py\n+++ b/src/plone/volto/behaviors/preview_link.py\n@@ -1,5 +1,5 @@\n from plone import api\n-from plone.app.z3cform.widget import RelatedItemsFieldWidget\n+from plone.app.z3cform.widgets.relateditems import RelatedItemsFieldWidget\n from plone.autoform import directives\n from plone.autoform.interfaces import IFormFieldProvider\n from plone.base.interfaces import IImageScalesFieldAdapter\ndiff --git a/src/plone/volto/browser/breadcrumbs.py b/src/plone/volto/browser/breadcrumbs.py\nindex 9799865..690b5a7 100644\n--- a/src/plone/volto/browser/breadcrumbs.py\n+++ b/src/plone/volto/browser/breadcrumbs.py\n@@ -1,10 +1,10 @@\n from Acquisition import aq_base\n from Acquisition import aq_inner\n from Acquisition import aq_parent\n-from plone.app.layout.navigation.interfaces import INavigationRoot\n-from plone.app.layout.navigation.root import getNavigationRoot\n from plone.base.defaultpage import check_default_page_via_view\n from plone.base.interfaces import IHideFromBreadcrumbs\n+from plone.base.interfaces import INavigationRoot\n+from plone.base.navigationroot import get_navigation_root\n from plone.base.utils import pretty_title_or_id\n from Products.CMFPlone.browser.interfaces import INavigationBreadcrumbs\n from Products.CMFPlone.browser.navigation import get_view_url\n@@ -42,7 +42,7 @@ def breadcrumbs(self):\n if IHideFromBreadcrumbs.providedBy(context):\n return base\n \n- rootPath = getNavigationRoot(context)\n+ rootPath = get_navigation_root(context)\n itemPath = "/".join(context.getPhysicalPath())\n \n # don\'t show default pages in breadcrumbs or pages above the navigation\ndiff --git a/src/plone/volto/browser/navigation.py b/src/plone/volto/browser/navigation.py\nindex 66941a8..a0c6bf8 100644\n--- a/src/plone/volto/browser/navigation.py\n+++ b/src/plone/volto/browser/navigation.py\n@@ -1,8 +1,8 @@\n from Acquisition import aq_inner\n from Missing import Missing\n-from plone.app.layout.navigation.root import getNavigationRoot\n from plone.base import utils\n from plone.base.interfaces import INavigationSchema\n+from plone.base.navigationroot import get_navigation_root\n from plone.registry.interfaces import IRegistry\n from Products.CMFCore.utils import getToolByName\n from Products.CMFPlone.browser.interfaces import INavigationTabs\n@@ -28,7 +28,7 @@ def _getNavQuery(self):\n else:\n query = {}\n \n- query["path"] = {"query": getNavigationRoot(self.context), "depth": 1}\n+ query["path"] = {"query": get_navigation_root(self.context), "depth": 1}\n query["portal_type"] = [t for t in navigation_settings.displayed_types]\n query["sort_on"] = navigation_settings.sort_tabs_on\n if navigation_settings.sort_tabs_reversed:\ndiff --git a/src/plone/volto/coresandbox/example.py b/src/plone/volto/coresandbox/example.py\nindex 535ac7e..675b00f 100644\n--- a/src/plone/volto/coresandbox/example.py\n+++ b/src/plone/volto/coresandbox/example.py\n@@ -1,9 +1,9 @@\n from plone.app.textfield import RichText\n from plone.app.vocabularies.catalog import CatalogSource\n from plone.app.vocabularies.catalog import StaticCatalogVocabulary\n-from plone.app.z3cform.widget import AjaxSelectFieldWidget\n-from plone.app.z3cform.widget import RelatedItemsFieldWidget\n-from plone.app.z3cform.widget import SelectFieldWidget\n+from plone.app.z3cform.widgets.relateditems import RelatedItemsFieldWidget\n+from plone.app.z3cform.widgets.select import AjaxSelectFieldWidget\n+from plone.app.z3cform.widgets.select import Select2FieldWidget\n from plone.autoform import directives\n from plone.dexterity.content import Container\n from plone.namedfile.field import NamedBlobFile\n@@ -183,7 +183,7 @@ class IExample(model.Schema):\n required=False,\n )\n \n- directives.widget(choice_field_select=SelectFieldWidget)\n+ directives.widget(choice_field_select=Select2FieldWidget)\n choice_field_select = schema.Choice(\n title="Choicefield with select2 widget",\n description="zope.schema.Choice",\n@@ -214,7 +214,7 @@ class IExample(model.Schema):\n default=[],\n )\n \n- directives.widget(list_field_select=SelectFieldWidget)\n+ directives.widget(list_field_select=Select2FieldWidget)\n list_field_select = schema.List(\n title="List field with select widget",\n description="zope.schema.List",\n@@ -437,7 +437,7 @@ class IExample(model.Schema):\n )\n directives.widget(\n "relationchoice_field_select",\n- SelectFieldWidget,\n+ Select2FieldWidget,\n )\n \n relationchoice_field_radio = RelationChoice(\n@@ -465,7 +465,7 @@ class IExample(model.Schema):\n )\n directives.widget(\n "relationlist_field_select",\n- SelectFieldWidget,\n+ Select2FieldWidget,\n pattern_options={\n "closeOnSelect": False, # Select2 option to leave dropdown open for multiple selection\n },\n@@ -620,7 +620,7 @@ class IExample(model.Schema):\n )\n directives.widget(\n "uuid_choice_field_select",\n- SelectFieldWidget,\n+ Select2FieldWidget,\n )\n \n uuid_choice_field_radio = schema.Choice(\n@@ -648,7 +648,7 @@ class IExample(model.Schema):\n )\n directives.widget(\n "uuid_list_field_select",\n- SelectFieldWidget,\n+ Select2FieldWidget,\n pattern_options={\n "closeOnSelect": False, # Select2 option to leave dropdown open for multiple selection\n },\ndiff --git a/src/plone/volto/profiles/default/registry.xml b/src/plone/volto/profiles/default/registry.xml\nindex aa8d206..1a97e36 100644\n--- a/src/plone/volto/profiles/default/registry.xml\n+++ b/src/plone/volto/profiles/default/registry.xml\n@@ -2,7 +2,7 @@\n \n \n \n False\n@@ -14,7 +14,7 @@\n \n \n \n@@ -23,7 +23,7 @@\n \n \n \ndiff --git a/src/plone/volto/testing.py b/src/plone/volto/testing.py\nindex d5f4304..2fb6677 100644\n--- a/src/plone/volto/testing.py\n+++ b/src/plone/volto/testing.py\n@@ -7,7 +7,7 @@\n from plone.app.testing import setRoles\n from plone.app.testing import TEST_USER_ID\n from plone.distribution.testing.layer import PloneDistributionFixture\n-from plone.testing import z2\n+from plone.testing import zope\n \n import plone.app.caching # noQA\n import plone.app.discussion # noQA\n@@ -62,13 +62,17 @@ class PloneVoltoCoreLayer(PloneSandboxLayer):\n \n \n PLONE_VOLTO_CORE_FUNCTIONAL_TESTING = FunctionalTesting(\n- bases=(PLONE_VOLTO_CORE_FIXTURE, z2.ZSERVER_FIXTURE),\n+ bases=(PLONE_VOLTO_CORE_FIXTURE, zope.WSGI_SERVER_FIXTURE),\n name="PloneVoltoCoreLayer:FunctionalTesting",\n )\n \n \n PLONE_VOLTO_CORE_ACCEPTANCE_TESTING = FunctionalTesting(\n- bases=(PLONE_VOLTO_CORE_FIXTURE, REMOTE_LIBRARY_BUNDLE_FIXTURE, z2.ZSERVER_FIXTURE),\n+ bases=(\n+ PLONE_VOLTO_CORE_FIXTURE,\n+ REMOTE_LIBRARY_BUNDLE_FIXTURE,\n+ zope.WSGI_SERVER_FIXTURE,\n+ ),\n name="PloneVoltoCoreLayer:AcceptanceTesting",\n )\n \n@@ -108,7 +112,7 @@ def setUpPloneSite(self, portal):\n \n \n PLONE_VOLTO_CORESANDBOX_FUNCTIONAL_TESTING = FunctionalTesting(\n- bases=(PLONE_VOLTO_CORESANDBOX_FIXTURE, z2.ZSERVER_FIXTURE),\n+ bases=(PLONE_VOLTO_CORESANDBOX_FIXTURE, zope.WSGI_SERVER_FIXTURE),\n name="PloneVoltoCoreSandboxLayer:FunctionalTesting",\n )\n \n@@ -117,7 +121,7 @@ def setUpPloneSite(self, portal):\n bases=(\n PLONE_VOLTO_CORESANDBOX_FIXTURE,\n REMOTE_LIBRARY_BUNDLE_FIXTURE,\n- z2.ZSERVER_FIXTURE,\n+ zope.WSGI_SERVER_FIXTURE,\n ),\n name="PloneVoltoCoreSandboxLayer:AcceptanceTesting",\n )\n@@ -144,6 +148,6 @@ def setUpPloneSite(self, portal):\n \n \n PLONE_VOLTO_MIGRATION_FUNCTIONAL_TESTING = FunctionalTesting(\n- bases=(PLONE_VOLTO_MIGRATION_FIXTURE, z2.ZSERVER_FIXTURE),\n+ bases=(PLONE_VOLTO_MIGRATION_FIXTURE, zope.WSGI_SERVER_FIXTURE),\n name="PloneVoltoMigrationLayer:FunctionalTesting",\n )\n' +A news/6.bugfix +M plone/app/event/__init__.py + +b'diff --git a/news/6.bugfix b/news/6.bugfix\nnew file mode 100644\nindex 00000000..b000847d\n--- /dev/null\n+++ b/news/6.bugfix\n@@ -0,0 +1,5 @@\n+Support ``icalendar`` 6 by forcing it to use its ``pytz`` timezone implementation.\n+The new ``zoneinfo`` support in ``icalendar`` 6 does not work for us yet, giving indexing problems.\n+So we call ``icalendar.use_pytz`` at startup.\n+If this fails, we must be using an older version where ``pytz`` is the only option anyway, so we ignore this.\n+[maurits]\ndiff --git a/plone/app/event/__init__.py b/plone/app/event/__init__.py\nindex bac87e2c..62ed906e 100644\n--- a/plone/app/event/__init__.py\n+++ b/plone/app/event/__init__.py\n@@ -1,10 +1,27 @@\n from AccessControl.Permission import addPermission\n from zope.i18nmessageid import MessageFactory\n \n+import icalendar\n+import logging\n \n+\n+logger = logging.getLogger(__name__)\n packageName = __name__\n _ = MessageFactory("plone")\n \n+# We are not yet ready to use the standard zoneinfo implementation\n+# introduced in icalendar 6. For starters, the tests fail when\n+# Products.DateRecurringIndex.index.index_object is called:\n+# SystemError: returned a result with an exception set\n+try:\n+ icalendar.use_pytz()\n+ logger.info("icalendar has been set up to use pytz instead of zoneinfo.")\n+except AttributeError:\n+ # If use_pytz does not exist, we either have an older icalender version\n+ # that only supports pytz anyway, or we have a newer version that no\n+ # longer supports it at all.\n+ pass\n+\n # BBB Permissions\n PORTAL_ADD_PERMISSION = "Add portal events" # CMFCalendar/ATCT permissions\n \n'