Skip to content
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: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ Bug fixes
- Fix ``VALUE`` parameter handling: ``datetime.date`` objects now correctly set ``VALUE=DATE`` parameter when added to properties like ``EXDATE``, ``RDATE``, and ``DTSTART``. The ``VALUE`` parameter is also properly used when parsing iCalendar data. See :issue:`349`.
- Fix URL-encoded characters being incorrectly unescaped during content line parsing. The parser now properly handles backslash escaping and double-quoted sections without corrupting URL-encoded values like ``%3A`` (colon) in DESCRIPTION fields. Added ``unescape_backslash()`` function to separate :rfc:`5545` backslash escaping from URL encoding. Optimized implementation using regex for single-pass processing. Added type hints to ``Contentline.parts()`` method and comprehensive unit tests. See :issue:`355`.
- `make livehtml` now reloads with code changes. See :issue:`931`.
- Added tests for tools, vFloat, vBinary, vGeo, and vTodo to improve unit test coverage. :issue:`698`


6.3.1 (2025-05-20)
Expand Down
3 changes: 3 additions & 0 deletions src/icalendar/tests/prop/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def test_prop_vFloat(self):
assert vFloat(1.0).to_ical() == b"1.0"
assert vFloat.from_ical("42") == 42.0
assert vFloat(42).to_ical() == b"42.0"
assert vFloat(1.2).ical_value == 1.2
self.assertRaises(ValueError, vFloat.from_ical, "1s3")

def test_prop_vInt(self):
Expand Down Expand Up @@ -258,6 +259,8 @@ def test_prop_vGeo(self):

assert vGeo(g).to_ical() == "37.386013;-122.082932"

assert hash(vGeo(g)) == hash(g)

self.assertRaises(ValueError, vGeo, "g")
self.assertRaises(ValueError, vGeo.from_ical, "1s3;1s3")

Expand Down
5 changes: 5 additions & 0 deletions src/icalendar/tests/prop/test_vBinary.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,8 @@ def test_ical_value():
"""ical_value property returns the string value."""
magic_string = base64.b64encode(b"magic string")
assert vBinary(magic_string).ical_value == base64.b64decode(magic_string)


def test_hash():
obj = vBinary(b"hashed text")
assert hash(obj) == hash(b"hashed text")
22 changes: 22 additions & 0 deletions src/icalendar/tests/test_issue_662_component_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,3 +774,25 @@ def test_get_alarm_triggers_repeated(alarms, file, triggers, duration, repeat):
assert triggers[0] == expected[0]
for x, y in itertools.pairwise(triggers):
assert y - x == duration


@pytest.mark.parametrize(
"invalid_value",
[
object(),
"invalid string",
123,
date(2024, 1, 1),
],
)
@pytest.mark.parametrize("Component", [Todo, Event])
def test_set_duration_invalid_type(Component, invalid_value):
"""Test that setting duration with a non-timedelta raises TypeError.

This ensures that we get the expected error message:
'Use timedelta, not {type}.'
"""
component = Component()
with pytest.raises(TypeError) as e:
component.duration = invalid_value
assert e.value.args[0] == f"Use timedelta, not {type(invalid_value).__name__}."
12 changes: 12 additions & 0 deletions src/icalendar/tests/test_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from datetime import datetime

from icalendar.tools import normalize_pytz


def test_normalize_pytz(pytz_only):
import pytz

tz = pytz.timezone("Europe/London")
pytz_dt = tz.localize(datetime(2024, 1, 1, 10, 0, 0))
result = normalize_pytz(pytz_dt)
assert result.tzinfo == pytz_dt.tzinfo