Skip to content

Icalendar version 6 #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 7 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -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"
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
11 changes: 6 additions & 5 deletions test-requirements.txt
Original file line number Diff line number Diff line change
@@ -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
62 changes: 17 additions & 45 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -36,16 +35,21 @@ 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):
return getattr(self, name.replace("-", "_"))

@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."""
Expand All @@ -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()
Expand Down Expand Up @@ -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()
Expand All @@ -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


Expand Down
3 changes: 2 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
Loading