Skip to content

Deprecate implicit string file-path reading in Component.from_ical - #1436

Closed
uwezkhan wants to merge 1 commit into
collective:mainfrom
uwezkhan:fix/deprecate-implicit-string-path
Closed

Deprecate implicit string file-path reading in Component.from_ical#1436
uwezkhan wants to merge 1 commit into
collective:mainfrom
uwezkhan:fix/deprecate-implicit-string-path

Conversation

@uwezkhan

@uwezkhan uwezkhan commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Component.from_ical now warns when you hand it a file path as a string. It still reads the file as before, but this is deprecated: in icalendar 8 a string will always be parsed as calendar data, never treated as a path. If you want to read from a file, pass a pathlib.Path.


📚 Documentation preview 📚: https://icalendar--1436.org.readthedocs.build/en/1436/

Right now, if you pass from_ical a single-line string that happens to be
the path of an existing file, it quietly reads that file off disk. That's
surprising and a little risky, so warn when it happens and line the
behaviour up for removal in icalendar 8. To read a file, pass a Path.

Refs collective#1362
@read-the-docs-community

read-the-docs-community Bot commented Jun 3, 2026

Copy link
Copy Markdown

Documentation build overview

📚 icalendar | 🛠️ Build #32974615 | 📁 Comparing 3d2eff5 against latest (02d750d)

  🔍 Preview build  

3 files changed
± 404.html
± reference/api/icalendar.cal.component.html
± _modules/icalendar/cal/component.html

@uwezkhan
uwezkhan force-pushed the fix/deprecate-implicit-string-path branch from 4fa9cfa to 3d2eff5 Compare June 3, 2026 14:37
@stevepiercy

Copy link
Copy Markdown
Member

@uwezkhan thanks for leading the charge. However, there needs to be a discussion about whether to deprecate a feature before it's implemented. I propose that you create a new issue referencing this PR, as well as the related discussion in #1362, where the maintainers can discuss and evaluate the proposed deprecation. Would that work for you? Please let me know. Thank you!

@uwezkhan

uwezkhan commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the suggestion @stevepiercy . That sounds reasonable to me.

I will open an issue to discuss the idea separately and reference both this PR and the discussion in #1362 so the maintainers can decide whether this is something worth pursuing before any implementation changes.

pchopinet pushed a commit to JaaJSoft/workspace that referenced this pull request Jun 24, 2026
Bumps [icalendar](https://github.com/collective/icalendar) from 7.1.3 to
7.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/collective/icalendar/releases">icalendar's
releases</a>.</em></p>
<blockquote>
<h2>v7.2.0</h2>
<p>To view the changes, please see the <a
href="https://icalendar.readthedocs.io/en/latest/reference/changelog.html">Changelog</a>.
This release can be installed from <a
href="https://pypi.org/project/icalendar/#history">PyPI</a>.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/collective/icalendar/blob/main/CHANGES.rst">icalendar's
changelog</a>.</em></p>
<blockquote>
<h2>7.2.0 (2026-06-23)</h2>
<p>Removals and deprecations</p>
<pre><code>
- Deprecated :func:`icalendar.parser.string.foldline` as a private
function for icalendar version 8. @IoannaGiag (`Issue
[#1011](collective/icalendar#1011)
&lt;https://github.com/collective/icalendar/issues/1011&gt;`_)
- Deprecated :func:`icalendar.parser.string.escape_char`,
:func:`icalendar.parser.string.unescape_char`,
:func:`icalendar.parser.string.escape_string`, and
:func:`icalendar.parser.string.unescape_string` using the standard
``deprecate_for_version_8`` wrapper as per issue
[#1405](collective/icalendar#1405). (`Issue
[#1405](collective/icalendar#1405)
&lt;https://github.com/collective/icalendar/issues/1405&gt;`_)
<p>New features</p>
<pre><code>
- Created an
:attr:`~icalendar.prop.recur.frequency.vFrequency.ical_value` property
for the :class:`~icalendar.prop.recur.frequency.vFrequency` component,
mirroring the existing pattern on
:class:`~icalendar.prop.recur.weekday.vWeekday`. @mvanhorn (`Issue
[#876](collective/icalendar#876)
&amp;lt;https://github.com/collective/icalendar/issues/876&amp;gt;`_)
- Created an :attr:`~icalendar.prop.geo.vGeo.ical_value` property for
the :class:`~icalendar.prop.geo.vGeo` component. @IoannaGiag (`Issue
[#876](collective/icalendar#876)
&amp;lt;https://github.com/collective/icalendar/issues/876&amp;gt;`_)
- Added type hints to component methods. @Priyanshu-pulak (`Issue
[#938](collective/icalendar#938)
&amp;lt;https://github.com/collective/icalendar/issues/938&amp;gt;`_)
- Added test coverage for
:func:`icalendar.compatibility.deprecate_for_version_8`. AI disclosure:
I used GPT-5 Codex to help draft and refine the test and pull request
text. I reviewed the output and validated the change locally.
@iccccccccccccc (`Issue
[#1407](collective/icalendar#1407)
&amp;lt;https://github.com/collective/icalendar/issues/1407&amp;gt;`_)
- The :attr:`Alarm.uid &amp;lt;icalendar.cal.alarm.Alarm.uid&amp;gt;`
accessor now falls back to vendor-specific UID properties (the existing
``X-ALARMUID`` and the newly added ``X-EVOLUTION-ALARM-UID``) when no
canonical ``UID`` is present, so alarms exported by Evolution/GNOME
Calendar expose a usable identifier. ``single_string_property`` now
accepts an ordered list of fallback keys so further vendor aliases can
be added later. AI disclosure: I used GPT-5 Codex (via the Codex CLI) to
draft and refine this change and its tests; I reviewed and validated the
output locally. @mvanhorn (`Issue
[#1421](collective/icalendar#1421)
&amp;lt;https://github.com/collective/icalendar/issues/1421&amp;gt;`_)
- The ``rdates`` and ``exdates`` properties are now writable: assigning
a list replaces the ``RDATE``/``EXDATE`` values, ``del`` (or assigning
an empty list or ``None``) clears them, and assigning the value the
getter returns round-trips. Prepared with the assistance of an AI coding
agent (Anthropic's Claude). @gaoflow (`Issue
[#1442](collective/icalendar#1442)
&amp;lt;https://github.com/collective/icalendar/issues/1442&amp;gt;`_)


Bug fixes
~~~~~~~~~

- Strictly validate :class:`~icalendar.prop.dt.datetime.vDatetime`
values in :meth:`~icalendar.prop.dt.datetime.vDatetime.from_ical` and
reject malformed input. This also improves handling of values with a
``TZID`` prefix, per :rfc:`5545#section-3.3.5`, Form
[#3](collective/icalendar#3). @uwezkhan
(`Issue [#1361](collective/icalendar#1361)
&amp;lt;https://github.com/collective/icalendar/issues/1361&amp;gt;`_)
- Preserve an explicit ``VALUE`` parameter (for example
``RDATE;VALUE=PERIOD`` or ``TRIGGER;VALUE=DATE-TIME``) when converting
from jCal. Previously :meth:`Component.from_jcal
&amp;lt;icalendar.cal.component.Component.from_jcal&amp;gt;` dropped the
value type, which is encoded in the jCal type field rather than as a
parameter. Prepared with the assistance of an AI coding agent
(Anthropic's Claude Opus 4). @gaoflow @lcampanella98 (`Issue
[#1426](collective/icalendar#1426)
&amp;lt;https://github.com/collective/icalendar/issues/1426&amp;gt;`_)
- For a newline-free string that the operating system can't use as a
file path—for example, one containing an embedded null byte or one that
is too long—treat it as calendar data, instead of propagating an
:exc:`OSError` from :meth:`Component.from_ical
&amp;lt;icalendar.cal.component.Component.from_ical&amp;gt;`. Such input
now raises a consistent :exc:`ValueError` across platforms. The
string-versus-path boundary is now covered by tests. @uwezkhan (`Issue
[#1436](collective/icalendar#1436)
&amp;lt;https://github.com/collective/icalendar/issues/1436&amp;gt;`_)
- Accept the ``(dt, None)`` form that ``rdates``/``exdates`` return for
a single date when adding ``RDATE`` or ``EXDATE``, so
``event.add(&amp;quot;RDATE&amp;quot;, (dt, None))`` no longer raises
:exc:`TypeError` and the value round-trips. Prepared with the assistance
of an AI coding agent (Anthropic's Claude Opus 4). @gaoflow @texttheater
(`Issue [#1439](collective/icalendar#1439)
&amp;lt;https://github.com/collective/icalendar/issues/1439&amp;gt;`_)
- Anchored the value validation regular expressions with ``\Z`` instead
of ``$`` in :class:`~icalendar.prop.recur.weekday.vWeekday`,
:meth:`vDuration.from_ical
&amp;lt;icalendar.prop.dt.duration.vDuration.from_ical&amp;gt;`,
:class:`~icalendar.prop.dt.time.vTime` and
:class:`~icalendar.prop.dt.utc_offset.vUTCOffset`. ``$`` matches just
before a final ``\n``, so a value with a trailing line break was
accepted; for ``vWeekday`` the newline survived in the ``str`` value and
was re-emitted into RECUR output. @alhudz
- For iCalendar files that have thousands of bare line breaks, reduce
the content line parse time by a quadratic order of magnitude when
reading a component with :meth:`Component.from_ical
&amp;lt;icalendar.cal.component.Component.from_ical&amp;gt;`. @alhudz
- Parse a ``CATEGORIES`` value that contains an unescaped colon
correctly. ``TEXT`` values do not escape ``:``, so a category such as
``CATEGORIES:CONFIDENTIAL,http://example.com/tag`` was truncated to a
single ``//example.com/tag`` because the value boundary was found with
the last colon on the line instead of the first one outside the
parameters. @alhudz
- Parse and serialize jCal iteratively so that deeply nested components
no longer raise an uncaught :exc:`RecursionError`.
:meth:`Component.from_jcal
&amp;lt;icalendar.cal.component.Component.from_jcal&amp;gt;` and
:meth:`Component.to_jcal
&amp;lt;icalendar.cal.component.Component.to_jcal&amp;gt;` now handle
arbitrary nesting depth, matching the iterative iCal parser and
serializer. @arshsmith
- Preserve literal percent escapes in parameter values. The parameter
parser used ``%2C``/``%3A``/``%3B``/``%5C`` as internal markers for
backslash-escaped delimiters, so a value that already contained those
sequences (e.g. ``ALTREP=&amp;quot;http://x/a%2Cb&amp;quot;``) was
silently decoded to ``http://x/a,b``. The internal transport encoding
now escapes ``%`` itself, leaving real percent-encoded values untouched.
@alhudz
- Raise :class:`~icalendar.error.InvalidCalendar` instead of leaking
:exc:`OverflowError` when a ``DURATION`` value is too large for
:class:`datetime.timedelta`, for example, ``P999999999999999999W``.
Parsing a whole calendar now records such a value as an error, like any
other invalid property, rather than aborting the parse. @arshsmith
- Reject non-ASCII digits in :class:`~icalendar.prop.recur.month.vMonth`
(``BYMONTH``). ``str.isdigit`` is ``True`` for digits like the
Arabic-Indic ``١٢``, which was silently accepted and normalized to month
``12``, while characters such as ``²`` cleared the same guard and then
leaked a raw ``int()`` error. :meth:`vMonth.from_ical
&amp;lt;icalendar.prop.recur.month.vMonth.from_ical&amp;gt;` now rejects
both. @alhudz
- Reject non-finite FLOAT values in :meth:`vFloat.from_ical()
&amp;lt;icalendar.prop.float.vFloat.from_ical&amp;gt;` and
:meth:`vGeo.from_ical()
&amp;lt;icalendar.prop.geo.vGeo.from_ical&amp;gt;`. Inputs such as
``nan``, ``inf`` or an overflowing magnitude like ``1e999`` were
silently accepted, producing ``NaN``/``Infinity`` tokens in
:meth:`Component.to_json
&amp;lt;icalendar.cal.component.Component.to_json&amp;gt;` output that
are not valid JSON. @alhudz
- Strictly validate :class:`~icalendar.prop.dt.date.vDate` and
:class:`~icalendar.prop.dt.time.vTime` values in their ``from_ical``
methods and reject malformed input, matching the strictness added to
:class:`~icalendar.prop.dt.datetime.vDatetime`. Trailing data and
``int()`` quirks (underscores, whitespace, signs) are no longer silently
accepted, per :rfc:`5545#section-3.3.4` and :rfc:`5545#section-3.3.12`.
This change was prepared with AI assistance (Anthropic Claude, Opus
model, via Claude Code) used to research the relevant RFC grammar and
draft the validation and tests, all reviewed and verified locally.
@alhudz


Documentation
</code></pre>
<ul>
<li>Switch :file:<code>docs/how-to/usage.rst</code> from the deprecated
<code>.. code:: pycon</code> directive to <code>.. code-block::
pycon</code> for consistency with the rest of the documentation. <a
href="https://github.com/mvanhorn"><code>@​mvanhorn</code></a>
(<code>Issue [#626](collective/icalendar#626)
&amp;lt;https://github.com/collective/icalendar/issues/626&amp;gt;</code>_)</li>
<li>Added type hint for <code>encoding</code> parameter in
:func:<code>~icalendar.parser_tools.data_encode</code>. <a
href="https://github.com/cybs-joe"><code>@​cybs-joe</code></a>
(<code>Issue [#938](collective/icalendar#938)
&amp;lt;https://github.com/collective/icalendar/issues/938&amp;gt;</code>_)</li>
<li>Converted docstring of
:meth:<code>~icalendar.cal.component.Component.add</code> to Google
style. <a href="https://github.com/mvanhorn"><code>@​mvanhorn</code></a>
(<code>Issue
[#1072](collective/icalendar#1072)
&amp;lt;https://github.com/collective/icalendar/issues/1072&amp;gt;</code>_)</li>
<li>Fixed broken links and removed <code>:py</code> prefix in
:class:<code>icalendar.cal.calendar.Calendar</code> documentation. <a
href="https://github.com/lcampanella98"><code>@​lcampanella98</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)</li>
<li>Fixed broken link and removed <code>:py</code> prefix in the
:func:<code>~icalendar.parser.unescape_backslash</code> docstring. <a
href="https://github.com/vincere-mori"><code>@​vincere-mori</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)</li>
<li>Fixed broken documentation links in
:mod:<code>icalendar.alarms</code> and
:mod:<code>icalendar.cal.alarm</code>. <a
href="https://github.com/lcampanella98"><code>@​lcampanella98</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)</li>
<li>Fix unqualified cross-references in :attr:<code>Event.start
&amp;lt;icalendar.cal.event.Event.start&amp;gt;</code> and
:attr:<code>Event.start
&amp;lt;icalendar.cal.event.Event.end&amp;gt;</code> docstrings. <a
href="https://github.com/Esneider1107"><code>@​Esneider1107</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)</li>
<li>Fixed broken links in :mod:<code>icalendar.cal.free_busy</code>
documentation by using fully qualified
:class:<code>icalendar.cal.component.Component</code> attribute targets.
<a href="https://github.com/tsai135"><code>@​tsai135</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)
&lt;/tr&gt;&lt;/table&gt;
</code></pre></li>
</ul>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/collective/icalendar/commit/df9f30ab0f7cc4a39c5f7d12fabab462697642f7"><code>df9f30a</code></a>
Merge branch 'main' into 7.x</li>
<li><a
href="https://github.com/collective/icalendar/commit/fd6d5b1aadf13d88f8356c1f58d5ceff85f08a51"><code>fd6d5b1</code></a>
Fix 7.2.0 changelog: restore content for 938.chore entry</li>
<li><a
href="https://github.com/collective/icalendar/commit/e99b5159ec0febc3cceebe075e7f91c5cab27c7f"><code>e99b515</code></a>
Fix 7.2.0 changelog: restore full release notes</li>
<li><a
href="https://github.com/collective/icalendar/commit/a2ceb5538b665f24247e0cb707322a89fe0d58db"><code>a2ceb55</code></a>
version 7.2.0</li>
<li><a
href="https://github.com/collective/icalendar/commit/87d7ce2fb96ca5d4c539664701f32c0fc9686ba9"><code>87d7ce2</code></a>
Merge pull request <a
href="https://redirect.github.com/collective/icalendar/issues/1495">#1495</a>
from collective/dependabot/github_actions/github-act...</li>
<li><a
href="https://github.com/collective/icalendar/commit/6f7743d5bb728bb613c3a6b8dc7fff44ea0be483"><code>6f7743d</code></a>
Bump actions/checkout in the github-actions group across 1
directory</li>
<li><a
href="https://github.com/collective/icalendar/commit/ceae0e3d2d8bc72006554382e04a0ddc178c75b9"><code>ceae0e3</code></a>
Remove <code>rtd-pr-preview.yml</code> from the workflows (<a
href="https://redirect.github.com/collective/icalendar/issues/1496">#1496</a>)</li>
<li><a
href="https://github.com/collective/icalendar/commit/a760432ded122e86a8be3913062d60279c5f6eee"><code>a760432</code></a>
Merge pull request <a
href="https://redirect.github.com/collective/icalendar/issues/1454">#1454</a>
from arshsmith/fix/jcal-iterative-parsing</li>
<li><a
href="https://github.com/collective/icalendar/commit/4cc90aebb2461be154df54c4367d878e09249bf1"><code>4cc90ae</code></a>
Merge branch 'main' into fix/jcal-iterative-parsing</li>
<li><a
href="https://github.com/collective/icalendar/commit/96ee28f8552df69b5fb82839dbf9e2b95c6e5b05"><code>96ee28f</code></a>
Merge pull request <a
href="https://redirect.github.com/collective/icalendar/issues/1446">#1446</a>
from alhudz/strict-date-time-from-ical</li>
<li>Additional commits viewable in <a
href="https://github.com/collective/icalendar/compare/v7.1.3...v7.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=icalendar&package-manager=uv&previous-version=7.1.3&new-version=7.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
martimlobao pushed a commit to martimlobao/regybox that referenced this pull request Jun 29, 2026
Bumps [icalendar](https://github.com/collective/icalendar) from 7.1.2 to
7.2.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/collective/icalendar/releases">icalendar's
releases</a>.</em></p>
<blockquote>
<h2>v7.2.0</h2>
<p>To view the changes, please see the <a
href="https://icalendar.readthedocs.io/en/latest/reference/changelog.html">Changelog</a>.
This release can be installed from <a
href="https://pypi.org/project/icalendar/#history">PyPI</a>.</p>
<h2>v7.1.3</h2>
<p>To view the changes, please see the <a
href="https://icalendar.readthedocs.io/en/latest/reference/changelog.html">Changelog</a>.
This release can be installed from <a
href="https://pypi.org/project/icalendar/#history">PyPI</a>.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/collective/icalendar/blob/main/CHANGES.rst">icalendar's
changelog</a>.</em></p>
<blockquote>
<h2>7.2.0 (2026-06-23)</h2>
<p>Removals and deprecations</p>
<pre><code>
- Deprecated :func:`icalendar.parser.string.foldline` as a private
function for icalendar version 8. @IoannaGiag (`Issue
[#1011](collective/icalendar#1011)
&lt;https://github.com/collective/icalendar/issues/1011&gt;`_)
- Deprecated :func:`icalendar.parser.string.escape_char`,
:func:`icalendar.parser.string.unescape_char`,
:func:`icalendar.parser.string.escape_string`, and
:func:`icalendar.parser.string.unescape_string` using the standard
``deprecate_for_version_8`` wrapper as per issue
[#1405](collective/icalendar#1405). (`Issue
[#1405](collective/icalendar#1405)
&lt;https://github.com/collective/icalendar/issues/1405&gt;`_)
<p>New features</p>
<pre><code>
- Created an
:attr:`~icalendar.prop.recur.frequency.vFrequency.ical_value` property
for the :class:`~icalendar.prop.recur.frequency.vFrequency` component,
mirroring the existing pattern on
:class:`~icalendar.prop.recur.weekday.vWeekday`. @mvanhorn (`Issue
[#876](collective/icalendar#876)
&amp;lt;https://github.com/collective/icalendar/issues/876&amp;gt;`_)
- Created an :attr:`~icalendar.prop.geo.vGeo.ical_value` property for
the :class:`~icalendar.prop.geo.vGeo` component. @IoannaGiag (`Issue
[#876](collective/icalendar#876)
&amp;lt;https://github.com/collective/icalendar/issues/876&amp;gt;`_)
- Added type hints to component methods. @Priyanshu-pulak (`Issue
[#938](collective/icalendar#938)
&amp;lt;https://github.com/collective/icalendar/issues/938&amp;gt;`_)
- Added test coverage for
:func:`icalendar.compatibility.deprecate_for_version_8`. AI disclosure:
I used GPT-5 Codex to help draft and refine the test and pull request
text. I reviewed the output and validated the change locally.
@iccccccccccccc (`Issue
[#1407](collective/icalendar#1407)
&amp;lt;https://github.com/collective/icalendar/issues/1407&amp;gt;`_)
- The :attr:`Alarm.uid &amp;lt;icalendar.cal.alarm.Alarm.uid&amp;gt;`
accessor now falls back to vendor-specific UID properties (the existing
``X-ALARMUID`` and the newly added ``X-EVOLUTION-ALARM-UID``) when no
canonical ``UID`` is present, so alarms exported by Evolution/GNOME
Calendar expose a usable identifier. ``single_string_property`` now
accepts an ordered list of fallback keys so further vendor aliases can
be added later. AI disclosure: I used GPT-5 Codex (via the Codex CLI) to
draft and refine this change and its tests; I reviewed and validated the
output locally. @mvanhorn (`Issue
[#1421](collective/icalendar#1421)
&amp;lt;https://github.com/collective/icalendar/issues/1421&amp;gt;`_)
- The ``rdates`` and ``exdates`` properties are now writable: assigning
a list replaces the ``RDATE``/``EXDATE`` values, ``del`` (or assigning
an empty list or ``None``) clears them, and assigning the value the
getter returns round-trips. Prepared with the assistance of an AI coding
agent (Anthropic's Claude). @gaoflow (`Issue
[#1442](collective/icalendar#1442)
&amp;lt;https://github.com/collective/icalendar/issues/1442&amp;gt;`_)


Bug fixes
~~~~~~~~~

- Strictly validate :class:`~icalendar.prop.dt.datetime.vDatetime`
values in :meth:`~icalendar.prop.dt.datetime.vDatetime.from_ical` and
reject malformed input. This also improves handling of values with a
``TZID`` prefix, per :rfc:`5545#section-3.3.5`, Form
[#3](collective/icalendar#3). @uwezkhan
(`Issue [#1361](collective/icalendar#1361)
&amp;lt;https://github.com/collective/icalendar/issues/1361&amp;gt;`_)
- Preserve an explicit ``VALUE`` parameter (for example
``RDATE;VALUE=PERIOD`` or ``TRIGGER;VALUE=DATE-TIME``) when converting
from jCal. Previously :meth:`Component.from_jcal
&amp;lt;icalendar.cal.component.Component.from_jcal&amp;gt;` dropped the
value type, which is encoded in the jCal type field rather than as a
parameter. Prepared with the assistance of an AI coding agent
(Anthropic's Claude Opus 4). @gaoflow @lcampanella98 (`Issue
[#1426](collective/icalendar#1426)
&amp;lt;https://github.com/collective/icalendar/issues/1426&amp;gt;`_)
- For a newline-free string that the operating system can't use as a
file path—for example, one containing an embedded null byte or one that
is too long—treat it as calendar data, instead of propagating an
:exc:`OSError` from :meth:`Component.from_ical
&amp;lt;icalendar.cal.component.Component.from_ical&amp;gt;`. Such input
now raises a consistent :exc:`ValueError` across platforms. The
string-versus-path boundary is now covered by tests. @uwezkhan (`Issue
[#1436](collective/icalendar#1436)
&amp;lt;https://github.com/collective/icalendar/issues/1436&amp;gt;`_)
- Accept the ``(dt, None)`` form that ``rdates``/``exdates`` return for
a single date when adding ``RDATE`` or ``EXDATE``, so
``event.add(&amp;quot;RDATE&amp;quot;, (dt, None))`` no longer raises
:exc:`TypeError` and the value round-trips. Prepared with the assistance
of an AI coding agent (Anthropic's Claude Opus 4). @gaoflow @texttheater
(`Issue [#1439](collective/icalendar#1439)
&amp;lt;https://github.com/collective/icalendar/issues/1439&amp;gt;`_)
- Anchored the value validation regular expressions with ``\Z`` instead
of ``$`` in :class:`~icalendar.prop.recur.weekday.vWeekday`,
:meth:`vDuration.from_ical
&amp;lt;icalendar.prop.dt.duration.vDuration.from_ical&amp;gt;`,
:class:`~icalendar.prop.dt.time.vTime` and
:class:`~icalendar.prop.dt.utc_offset.vUTCOffset`. ``$`` matches just
before a final ``\n``, so a value with a trailing line break was
accepted; for ``vWeekday`` the newline survived in the ``str`` value and
was re-emitted into RECUR output. @alhudz
- For iCalendar files that have thousands of bare line breaks, reduce
the content line parse time by a quadratic order of magnitude when
reading a component with :meth:`Component.from_ical
&amp;lt;icalendar.cal.component.Component.from_ical&amp;gt;`. @alhudz
- Parse a ``CATEGORIES`` value that contains an unescaped colon
correctly. ``TEXT`` values do not escape ``:``, so a category such as
``CATEGORIES:CONFIDENTIAL,http://example.com/tag`` was truncated to a
single ``//example.com/tag`` because the value boundary was found with
the last colon on the line instead of the first one outside the
parameters. @alhudz
- Parse and serialize jCal iteratively so that deeply nested components
no longer raise an uncaught :exc:`RecursionError`.
:meth:`Component.from_jcal
&amp;lt;icalendar.cal.component.Component.from_jcal&amp;gt;` and
:meth:`Component.to_jcal
&amp;lt;icalendar.cal.component.Component.to_jcal&amp;gt;` now handle
arbitrary nesting depth, matching the iterative iCal parser and
serializer. @arshsmith
- Preserve literal percent escapes in parameter values. The parameter
parser used ``%2C``/``%3A``/``%3B``/``%5C`` as internal markers for
backslash-escaped delimiters, so a value that already contained those
sequences (e.g. ``ALTREP=&amp;quot;http://x/a%2Cb&amp;quot;``) was
silently decoded to ``http://x/a,b``. The internal transport encoding
now escapes ``%`` itself, leaving real percent-encoded values untouched.
@alhudz
- Raise :class:`~icalendar.error.InvalidCalendar` instead of leaking
:exc:`OverflowError` when a ``DURATION`` value is too large for
:class:`datetime.timedelta`, for example, ``P999999999999999999W``.
Parsing a whole calendar now records such a value as an error, like any
other invalid property, rather than aborting the parse. @arshsmith
- Reject non-ASCII digits in :class:`~icalendar.prop.recur.month.vMonth`
(``BYMONTH``). ``str.isdigit`` is ``True`` for digits like the
Arabic-Indic ``١٢``, which was silently accepted and normalized to month
``12``, while characters such as ``²`` cleared the same guard and then
leaked a raw ``int()`` error. :meth:`vMonth.from_ical
&amp;lt;icalendar.prop.recur.month.vMonth.from_ical&amp;gt;` now rejects
both. @alhudz
- Reject non-finite FLOAT values in :meth:`vFloat.from_ical()
&amp;lt;icalendar.prop.float.vFloat.from_ical&amp;gt;` and
:meth:`vGeo.from_ical()
&amp;lt;icalendar.prop.geo.vGeo.from_ical&amp;gt;`. Inputs such as
``nan``, ``inf`` or an overflowing magnitude like ``1e999`` were
silently accepted, producing ``NaN``/``Infinity`` tokens in
:meth:`Component.to_json
&amp;lt;icalendar.cal.component.Component.to_json&amp;gt;` output that
are not valid JSON. @alhudz
- Strictly validate :class:`~icalendar.prop.dt.date.vDate` and
:class:`~icalendar.prop.dt.time.vTime` values in their ``from_ical``
methods and reject malformed input, matching the strictness added to
:class:`~icalendar.prop.dt.datetime.vDatetime`. Trailing data and
``int()`` quirks (underscores, whitespace, signs) are no longer silently
accepted, per :rfc:`5545#section-3.3.4` and :rfc:`5545#section-3.3.12`.
This change was prepared with AI assistance (Anthropic Claude, Opus
model, via Claude Code) used to research the relevant RFC grammar and
draft the validation and tests, all reviewed and verified locally.
@alhudz


Documentation
</code></pre>
<ul>
<li>Switch :file:<code>docs/how-to/usage.rst</code> from the deprecated
<code>.. code:: pycon</code> directive to <code>.. code-block::
pycon</code> for consistency with the rest of the documentation. <a
href="https://github.com/mvanhorn"><code>@​mvanhorn</code></a>
(<code>Issue [#626](collective/icalendar#626)
&amp;lt;https://github.com/collective/icalendar/issues/626&amp;gt;</code>_)</li>
<li>Added type hint for <code>encoding</code> parameter in
:func:<code>~icalendar.parser_tools.data_encode</code>. <a
href="https://github.com/cybs-joe"><code>@​cybs-joe</code></a>
(<code>Issue [#938](collective/icalendar#938)
&amp;lt;https://github.com/collective/icalendar/issues/938&amp;gt;</code>_)</li>
<li>Converted docstring of
:meth:<code>~icalendar.cal.component.Component.add</code> to Google
style. <a href="https://github.com/mvanhorn"><code>@​mvanhorn</code></a>
(<code>Issue
[#1072](collective/icalendar#1072)
&amp;lt;https://github.com/collective/icalendar/issues/1072&amp;gt;</code>_)</li>
<li>Fixed broken links and removed <code>:py</code> prefix in
:class:<code>icalendar.cal.calendar.Calendar</code> documentation. <a
href="https://github.com/lcampanella98"><code>@​lcampanella98</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)</li>
<li>Fixed broken link and removed <code>:py</code> prefix in the
:func:<code>~icalendar.parser.unescape_backslash</code> docstring. <a
href="https://github.com/vincere-mori"><code>@​vincere-mori</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)</li>
<li>Fixed broken documentation links in
:mod:<code>icalendar.alarms</code> and
:mod:<code>icalendar.cal.alarm</code>. <a
href="https://github.com/lcampanella98"><code>@​lcampanella98</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)</li>
<li>Fix unqualified cross-references in :attr:<code>Event.start
&amp;lt;icalendar.cal.event.Event.start&amp;gt;</code> and
:attr:<code>Event.start
&amp;lt;icalendar.cal.event.Event.end&amp;gt;</code> docstrings. <a
href="https://github.com/Esneider1107"><code>@​Esneider1107</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)</li>
<li>Fixed broken links in :mod:<code>icalendar.cal.free_busy</code>
documentation by using fully qualified
:class:<code>icalendar.cal.component.Component</code> attribute targets.
<a href="https://github.com/tsai135"><code>@​tsai135</code></a>
(<code>Issue
[#1158](collective/icalendar#1158)
&amp;lt;https://github.com/collective/icalendar/issues/1158&amp;gt;</code>_)
&lt;/tr&gt;&lt;/table&gt;
</code></pre></li>
</ul>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/collective/icalendar/commit/df9f30ab0f7cc4a39c5f7d12fabab462697642f7"><code>df9f30a</code></a>
Merge branch 'main' into 7.x</li>
<li><a
href="https://github.com/collective/icalendar/commit/fd6d5b1aadf13d88f8356c1f58d5ceff85f08a51"><code>fd6d5b1</code></a>
Fix 7.2.0 changelog: restore content for 938.chore entry</li>
<li><a
href="https://github.com/collective/icalendar/commit/e99b5159ec0febc3cceebe075e7f91c5cab27c7f"><code>e99b515</code></a>
Fix 7.2.0 changelog: restore full release notes</li>
<li><a
href="https://github.com/collective/icalendar/commit/a2ceb5538b665f24247e0cb707322a89fe0d58db"><code>a2ceb55</code></a>
version 7.2.0</li>
<li><a
href="https://github.com/collective/icalendar/commit/87d7ce2fb96ca5d4c539664701f32c0fc9686ba9"><code>87d7ce2</code></a>
Merge pull request <a
href="https://redirect.github.com/collective/icalendar/issues/1495">#1495</a>
from collective/dependabot/github_actions/github-act...</li>
<li><a
href="https://github.com/collective/icalendar/commit/6f7743d5bb728bb613c3a6b8dc7fff44ea0be483"><code>6f7743d</code></a>
Bump actions/checkout in the github-actions group across 1
directory</li>
<li><a
href="https://github.com/collective/icalendar/commit/ceae0e3d2d8bc72006554382e04a0ddc178c75b9"><code>ceae0e3</code></a>
Remove <code>rtd-pr-preview.yml</code> from the workflows (<a
href="https://redirect.github.com/collective/icalendar/issues/1496">#1496</a>)</li>
<li><a
href="https://github.com/collective/icalendar/commit/a760432ded122e86a8be3913062d60279c5f6eee"><code>a760432</code></a>
Merge pull request <a
href="https://redirect.github.com/collective/icalendar/issues/1454">#1454</a>
from arshsmith/fix/jcal-iterative-parsing</li>
<li><a
href="https://github.com/collective/icalendar/commit/4cc90aebb2461be154df54c4367d878e09249bf1"><code>4cc90ae</code></a>
Merge branch 'main' into fix/jcal-iterative-parsing</li>
<li><a
href="https://github.com/collective/icalendar/commit/96ee28f8552df69b5fb82839dbf9e2b95c6e5b05"><code>96ee28f</code></a>
Merge pull request <a
href="https://redirect.github.com/collective/icalendar/issues/1446">#1446</a>
from alhudz/strict-date-time-from-ical</li>
<li>Additional commits viewable in <a
href="https://github.com/collective/icalendar/compare/v7.1.2...v7.2.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=icalendar&package-manager=uv&previous-version=7.1.2&new-version=7.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants