Repository: niccokunzmann/python-recurring-ical-events (language: python)

Issue:
icalendar version 6
Icalendar version 6 upgrades to zoneinfo.
It would be nice to use the switching functionality of icalendar in the tests to test with zoneinfo.

- fixture scope: module

Context:
- https://github.com/collective/icalendar/issues/630

<!-- POLAR PLEDGE BADGE START -->
<small>
<hr/>
We're using <a href="https://polar.sh/niccokunzmann">Polar.sh</a> so you can upvote and help fund this issue. We receive the funding once the issue is completed & confirmed by you. Thank you in advance for helping prioritize & fund our work.
</small>

<a href="https://polar.sh/niccokunzmann/python-recurring-ical-events/issues/141">
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://polar.sh/api/github/niccokunzmann/python-recurring-ical-events/issues/141/pledge.svg?darkmode=1">
  <img alt="Fund with Polar" src="https://polar.sh/api/github/niccokunzmann/python-recurring-ical-events/issues/141/pledge.svg">
</picture>
</a>
<!-- POLAR PLEDGE BADGE END -->



Discussion / hints:

Fix patch:
diff --git a/README.rst b/README.rst
index 182560d..f7741ef 100644
--- a/README.rst
+++ b/README.rst
@@ -326,6 +326,12 @@ To release new versions,
 Changelog
 ---------
 
+- v2.2.2
+
+  - Test support for ``icalendar==6.*``
+  - Remove Python 3.7 from tests and compatibility list
+  - Remove pytz from requirements
+
 - v2.2.1
 
   - Add support for multiple RRULE in events.
diff --git a/requirements.txt b/requirements.txt
index e295cb2..f8c9693 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,8 @@
-icalendar == 5.*
-pytz >= 2023.3
-python-dateutil >= 2.8.1
+# install requirements depending on python version
+# see https://www.python.org/dev/peps/pep-0508/#environment-markers
+
+icalendar >= 5.0.0, < 7.0.0
+python-dateutil >= 2.8.1, < 3.0.0
 x-wr-timezone == 0.*
+backports.zoneinfo; python_version == "3.7" or python_version == "3.8"
+tzdata; python_version >= "3.7"
diff --git a/setup.py b/setup.py
index 5f35ec3..4aa15c7 100644
--- a/setup.py
+++ b/setup.py
@@ -138,11 +138,11 @@ def run(self):
         "Operating System :: OS Independent",
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3 :: Only",
-        "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
         "Programming Language :: Python :: 3.11",
+        "Programming Language :: Python :: 3.12",
         development_state,
     ],
     zip_safe=True,
diff --git a/tox.ini b/tox.ini
index d588e6b..8bc6953 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,12 +5,13 @@
 
 [tox]
 skipsdist = True
-envlist = py37, py38, py39, py310, py311, py312
+envlist = py38, py39, py310, py311, py312
 
 [testenv]
 setenv = TMPDIR={envtmpdir}
 passenv = TZ
 deps =
+    --pre # allow alpha releases
     -r {toxinidir}/requirements.txt
     -r {toxinidir}/test-requirements.txt
 commands =


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 7e0e889..fd4b9aa 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -15,7 +15,6 @@ jobs:
       matrix:
         config:
         # [Python version, tox env, timezone]
-        - ["3.7",   "py37",  "Europe/Berlin"]
         - ["3.8",   "py38",  "Australia/Sydney"]
         - ["3.9",   "py39",  "UTC"]
         - ["3.10",  "py310", "Asia/Singapore"]
diff --git a/test-requirements.txt b/test-requirements.txt
index 94a0ac1..12058cd 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,9 +1,10 @@
+# install requirements depending on python version
+# see https://www.python.org/dev/peps/pep-0508/#environment-markers
+
+setuptools
 pytest
 pytest-cov
 restructuredtext-lint
 pygments
-x-wr-timezone >= 0.0.3
-# install requirements depending on python version
-# see https://www.python.org/dev/peps/pep-0508/#environment-markers
-backports.zoneinfo; python_version == "3.7" or python_version == "3.8"
-tzdata; python_version >= "3.7"
+pytz >= 2023.3
+icalendar >=6.0.0a0
diff --git a/test/conftest.py b/test/conftest.py
index f1cbc6e..23d50be 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -14,7 +14,6 @@
         import backports.zoneinfo as _zoneinfo
     except ImportError:
         _zoneinfo = None
-from x_wr_timezone import CalendarWalker
 
 HERE = Path(__file__).parent
 REPO = Path(HERE).parent
@@ -36,8 +35,13 @@ class ICSCalendars:
     Calendar = icalendar.Calendar
     components = None
 
+    def __init__(self, tzp):
+        """Create ICS calendars in a specific timezone."""
+        self.tzp = tzp
+
     def get_calendar(self, content):
         """Return the calendar given the content."""
+        self.tzp()
         return self.Calendar.from_ical(content)
 
     def __getitem__(self, name):
@@ -45,7 +49,7 @@ def __getitem__(self, name):
 
     @property
     def raw(self):
-        return ICSCalendars()
+        return ICSCalendars(self.tzp)
 
     def consistent_tz(self, dt):
         """Make the datetime consistent with the time zones used in these calendars."""
@@ -60,6 +64,9 @@ def _of(self, calendar):
             return of(calendar)
         return of(calendar, components=self.components)
 
+    def __repr__(self):
+        return f"{self.__class__.__name__}({self.tzp.__name__})"
+
 
 for calendar_path in CALENDARS_FOLDER.iterdir():
     content = calendar_path.read_bytes()
@@ -99,47 +106,17 @@ def walk(*args, **kw):
         return self._of(calendar)
 
 
-class ZoneInfoConverter(CalendarWalker):
-    """Visit a calendar and change all time zones to ZoneInfo"""
-
-    def walk_value_datetime(self, dt):
-        """Chnage timezone of datetime to zoneinfo"""
-        py_tz = dt.tzinfo
-        if py_tz is None:
-            return dt
-        name = py_tz.zone  # , py_tz.tzname(dt)
-        new_tz = _zoneinfo.ZoneInfo(name)  # create a zoneinfo from pytz time zone
-        return dt.astimezone(new_tz)
-
-
-class ZoneInfoCalendars(ICSCalendars):
-    """Collection of calendars using zoneinfo.ZoneInfo and not pytz."""
-
-    def __init__(self):
-        assert _zoneinfo is not None, "zoneinfo must exist to use these calendars"
-        self.changer = ZoneInfoConverter()
-
-    def get_calendar(self, content):
-        calendar = ICSCalendars.get_calendar(self, content)
-        zoneinfo_calendar = self.changer.walk(calendar)
-        #        if zoneinfo_calendar is calendar:
-        #            pytest.skip("ZoneInfo not in use. Already tested..")
-        return self._of(zoneinfo_calendar)
-
-    def consistent_tz(self, dt):
-        """To make the time zones consistent with this one, convert them to zoneinfo."""
-        return self.changer.walk_value_datetime(dt)
-
-
-calendar_params = [Calendars, ReversedCalendars]
-if _zoneinfo is not None:
-    calendar_params.append(ZoneInfoCalendars)
+@pytest.fixture(params=[icalendar.use_pytz, icalendar.use_zoneinfo], scope="module")
+def tzp(request):
+    """The timezone provider supported by icalendar."""
+    return request.param
 
 
 # for parametrizing fixtures, see https://docs.pytest.org/en/latest/fixture.html#parametrizing-fixtures
-@pytest.fixture(params=calendar_params, scope="module")
-def calendars(request):
-    return request.param()
+@pytest.fixture(params=[Calendars, ReversedCalendars], scope="module")
+def calendars(request, tzp):
+    """The calendars we can use in the tests."""
+    return request.param(tzp)
 
 
 @pytest.fixture()
@@ -154,11 +131,6 @@ def zoneinfo():
 
     Uses backports.zoneinfo or zoneinfo.
     """
-    if _zoneinfo is None:
-        pytest.skip(
-            "zoneinfo module not given. "
-            "Use pip install backports.zoneinfo to install it.",
-        )
     return _zoneinfo