Commit 0da4be0
fix(deps): update dependency caldav to v3 (#416)
> ℹ️ **Note**
>
> This PR body was truncated due to platform limits.
This PR contains the following updates:
| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [caldav](https://redirect.github.com/python-caldav/caldav)
([changelog](https://redirect.github.com/python-caldav/caldav/blob/master/CHANGELOG.md))
| `>=2.2.6,<3` → `>=3.1,<4` |

|

|
---
### Release Notes
<details>
<summary>python-caldav/caldav (caldav)</summary>
###
[`v3.1.0`](https://redirect.github.com/python-caldav/caldav/blob/HEAD/CHANGELOG.md#310---2026-03-19)
[Compare
Source](https://redirect.github.com/python-caldav/caldav/compare/v3.0.2...v3.1.0)
Highlights:
- **Fixups on the async support**. Perhaps the "sans-io" design concept
wasn't such a great idea - quite some gaps in the async support has been
identified and fixed,.
- **Multi-server `get_calendars()`:** a single `get_calendars()` call
can now span multiple config-file sections (including glob/wildcard
expansion), aggregating calendars from multiple servers into one
`CalendarCollection`. This was the idea (and has been implemented in my
`plann` project for quite some time), but fell short of getting into the
v3.0-release.
- Full async tutorial added to the documentation.
##### Added
- `get_icalendar_component()` returns a deep-copy of the inner
VEVENT/VTODO/VJOURNAL sub-component for read-only inspection, consistent
with the `get_icalendar_instance()` naming convention.
- `edit_icalendar_component()` context manager yields the inner
component for editing and delegates to `edit_icalendar_instance()` so
all borrow/state/save machinery is reused.
- `get_calendars()` now accepts a `config_section` value that is
expanded via `expand_config_section()`, so wildcards like `"work_*"` or
`"all"` resolve to multiple leaf sections; each section gets its own
`DAVClient` and all calendars are aggregated into a
`CalendarCollection`. `CalendarCollection` now closes all its clients on
context-manager exit.
- New config helper: `get_all_file_connection_params(config_file,
section)`.
- `PYTHON_CALDAV_USE_TEST_SERVER=1` (or `testconfig=True`) falls back to
automatically starting the first available enabled server from the
test-server registry when no `testing_allowed` config section is
present. Three new env vars (`PYTHON_CALDAV_TEST_EMBEDDED`,
`PYTHON_CALDAV_TEST_DOCKER`, `PYTHON_CALDAV_TEST_EXTERNAL`) control
which server categories are eligible. Per-server `priority:` keys in
config files are honoured.
- New `caldav/testing.py` (shipped with the package): `EmbeddedServer`,
`XandikosServer`, `RadicaleServer` — so pip-installed users can use
`PYTHON_CALDAV_USE_TEST_SERVER=1` without a source checkout.
##### Fixed
- `get_object_by_uid()` (and `get_event_by_uid()`, `get_todo_by_uid()`,
`get_journal_by_uid()`, and their deprecated aliases) raised `TypeError`
with async clients because `search()` returned a coroutine that was
iterated directly. Fixes
[#​642](https://redirect.github.com/python-caldav/caldav/issues/642)
- `complete()` and the save()-recurrence path were not awaited for async
clients.
- `uncomplete()`, `set_relation()`, `get_relatives()`, and `invite()`
lacked async dispatch.
- `_handle_reverse_relations()` called `get_relatives()` without
`await`, silently returning a coroutine.
- `get_calendar()` and `get_calendars()` were missing from the
`caldav.aio` re-export.
- `get_calendars(config_section=…)` silently ignored `calendar_name` and
`calendar_url` keys in config sections — they were stripped before
reaching the filter logic.
- `expand_config_section()` was not called when reading the config file,
so `contains:`-style meta-sections had no effect.
- `date` objects passed to `calendar.search()` or `calendar.searcher()`
as time-range boundaries now get coerced to UTC `datetime` before being
forwarded to `icalendar_searcher`, silencing the "Date-range searches
not well supported yet" warning.
- `XandikosServer.is_accessible()` now sends a minimal `PROPFIND`
requesting only `{DAV:}resourcetype` instead of an implicit `allprop`,
avoiding spurious `NotImplementedError` log lines from Xandikos during
test-server startup.
##### Tests and documentation
- Full async tutorial added: `docs/source/async_tutorial.rst`. Covers
the same ground as the sync tutorial plus a "Parallel Operations"
section demonstrating `asyncio.gather()`. The sync tutorial now links to
it.
- `docs/source/configfile.rst` has been rewritten and extended; tests
for `inherits` and env-var expansion added.
- `docs/source/tutorial.rst` rewritten and fixed.
- The caldav-server-tester tool is now documented in the config file
guide.
- Design notes on the dual-mode sync/async pattern and its trade-offs
added in `docs/source/`.
- Test server spin-up/teardown tweaked for reliability.
- CI: deptry and lychee link-checker fixups.
###
[`v3.0.2`](https://redirect.github.com/python-caldav/caldav/blob/HEAD/CHANGELOG.md#302---2026-03-15)
[Compare
Source](https://redirect.github.com/python-caldav/caldav/compare/v3.0.1...v3.0.2)
Highlight: Reintroducing debug communication dump functionality.
##### Fixed
- When environment variable `PYTHON_CALDAV_COMMDUMP` is given, caldav
communication is dumped to /tmp - details in
[#​248](https://redirect.github.com/python-caldav/caldav/issues/248)
. This is regarded as "fix" rather than "feature" as it was introduced
in v1.4.0 and accidentally dropped during the v3.0 refactoring.
Restored, with the dump logic extracted into a shared helper so both the
sync and async code paths benefit. Test code added to make sure it won't
disappear again. Fixes
[#​638](https://redirect.github.com/python-caldav/caldav/issues/638)
- `search()` raised `NotImplementedError` when a full calendar-query XML
was passed and the server does not support `search.comp-type.optional`.
This is a really rare and deprecated code path, but still
`NotImplementedError` isn't good. Now it falls back to a single REPORT
with the XML as-is. Fixes
[#​637](https://redirect.github.com/python-caldav/caldav/issues/637)
##### Tests and documentation
- All links to the RFC is now in a canonical format. Links in docstrings
and ReST-documentation follows the sphinx-standard. Fixes
[#​635](https://redirect.github.com/python-caldav/caldav/issues/635)
- pull request
[#​636](https://redirect.github.com/python-caldav/caldav/pull/636)
- I've decided to try to stick to the conventionalcommits standard. This
is documented in CONTRIBUTING.md, and I've added a pre-commit hook for
enforcing it (but it needs to be installed through pre-commit ... so I
will most likely have to police pull requests manually)
- Some code refactoring in the test code.
- Improved the lychee link testing setup
###
[`v3.0.1`](https://redirect.github.com/python-caldav/caldav/blob/HEAD/CHANGELOG.md#301---2026-03-04)
[Compare
Source](https://redirect.github.com/python-caldav/caldav/compare/v3.0.0...v3.0.1)
Highlights:
- Minor bugfix to support old versions of httpx
- New test server docker container: OX
- Minor other fixes and workarounds
- Started working on proper documentation for the 3.x-series
##### Test runs before release
- Xandikos, Radicale, all docker servers (including OX), an external
Zimbra server, but no other external servers.
##### Added
- **OX App Suite** included in the docker test servers. Compatibility
hints added. To get OX running it's needed to do an extra build step.
See `tests/docker-test-servers/ox/`. However, OX is undertested as both
the caldav-server-checker and the test suite does not play well with OX
(events with historic DTSTART etc are used, OX doesn't support that).
- New `search.unlimited-time-range` feature flag with a workaround in
`search.py` that injects a broad time range (1970–2126) for servers that
return an empty result set when no time range is specified (but this
still doesn't help to OX).
##### Fixed
- `AsyncDAVClient` failed to initialize when using httpx < 0.23.0
because `proxy=None` was unconditionally passed to `httpx.AsyncClient`
which did not accept a `proxy` keyword argument in older releases. Fixes
[#​632](https://redirect.github.com/python-caldav/caldav/issues/632)
- Stalwart (like purelymail) includes extra "not found" error data in
some responses. This could trigger a spurious `"Deviation from
expectations found"` log error in production, or an assertion failure in
debug mode.
##### Security
- UUID1 was replaced with UUID4 before releasing v3.0 ... some places.
Unfortunately I forgot to grep for UUID1 before preparing the release.
When UIDs are generated by UUID1, it may embed the host MAC address in
calendar data shared with third parties. Switched to UUID4 throughout.
##### Potentially Breaking Changes
- The compatibility-hint key `search.comp-type-optional` has been
renamed to `search.comp-type.optional` for consistency with the
dotted-key naming convention used elsewhere. If you have this key set in
a local server configuration, update it accordingly.
##### Documentation
Some minor improvements, including a fix for
[#​635](https://redirect.github.com/python-caldav/caldav/issues/635)
- use canonical RFC-links.
###
[`v3.0.0`](https://redirect.github.com/python-caldav/caldav/blob/HEAD/CHANGELOG.md#300---2026-03-03)
[Compare
Source](https://redirect.github.com/python-caldav/caldav/compare/v2.2.6...v3.0.0)
Version 3.0 should be fully backward-compatible with version 2.x - but
there are massive code changes in version 3.0, so if you're using the
Python CalDAV client library in some sharp production environment, I
would recommend to wait for two months before upgrading.
Highlights
- As always, lots of compatibility-tweaking. This release have probably
been tested on more server implementations than any earlier version.
- "Black Style" has been replaced with **ruff**. This causes quite some
minor changes to the code.
- **Full async support** -- New `AsyncDAVClient` and async domain
objects using a Sans-I/O architecture. The same `Calendar`, `Event`,
`Todo`, etc. objects work with both sync and async clients.
- Experimental **JMAP client** -- New `caldav.jmap` package with
`JMAPClient` and `AsyncJMAPClient` for servers implementing RFC 8620
(JMAP Core) and RFC 8984 (JMAP Calendars). Note that this is
experimental, and the public API may be changed in upcoming
minor-releases.
- **Overhaul of the official API** -- v3.0 comes with an improved, more
pythonic and more consistent API, but aims to be fully backeward
compatible. Some work has been done on the documentation, but full QA
and updates will have to wait for an upcoming patch release.
##### Test runs before release
- The built-in test-servers, of course: Radicale, Xandikos
- All the docker-based test servers: Nextcloud, Baikal, Bedework, CCS,
Cyrus, DAViCal, Davis, SOGo, Stalwart, Zimbra
- External servers and SaaS-providers:
- ECloud (NextCloud-based - big troubles due to ratelimiting and need
for manually "emptying the trashbin")
- Synology
- Zimbra Enterprise, hosted by my employer
- Robur (has some issues with transient errors)
- Posteo
- Purelymail (test run takes ages due to delays before search results
are ready)
The tests broke with lots of AuthorizationErrors with GMX. The tests
were running successfully towards GMX before releasing the last
alpha-release. It's probably a transient issue. I don't want to delay
the release by doing more research into it.
##### Breaking Changes
Be aware that some of the 2.x minor-versions also tagged some
"Potentially Breaking Changes" - so if you're upgrading i.e. from 2.1,
you may want to browse through the "Potentially Breaking Changes" for
the intermediate minor releases too.
- **Minimum Python version**: Python 3.10+ is now required (was 3.8+).
- **Test Server Configuration**: `tests/conf.py` has been removed and
`conf_private.py` will be ignored. See the Test Framework section below.
- **`caldav/objects.py` removed** -- the backward-compatibility
re-export shim has been deleted. Any code doing `from caldav.objects
import <something>` must be updated; all public symbols remain available
directly via `caldav` or from their respective submodules.
- **Config file parse errors now raise exceptions** --
`caldav.config.read_config()` now raises `ValueError` on YAML/JSON parse
errors instead of logging and returning an empty dict. This ensures
config errors are detected early.
##### Deprecated
The following have been deprecated and emit `DeprecationWarning`:
- `calendar.date_search()` - use `calendar.search()` instead
- `client.principals()` - use `client.search_principals()` instead
- `obj.split_expanded` - may be removed in a future version
- `obj.expand_rrule` - may be removed in a future version
- `.instance` property on calendar objects - use `.vobject_instance` or
`.icalendar_instance`
- `response.find_objects_and_props()` - use `response.results` instead
The `save_*`-methods are deprecated but do not yet emit warnings (see
[#​71](https://redirect.github.com/python-caldav/caldav/issues/71)):
- `calendar.save_event()` - use `calendar.add_event()` instead
- `calendar.save_todo()` - use `calendar.add_todo()` instead
- `calendar.save_journal()` - use `calendar.add_journal()` instead
- `calendar.save_object()` - use `calendar.add_object()` instead
Methods that fetch data from the server should use the `get_` prefix
(see
[#​92](https://redirect.github.com/python-caldav/caldav/issues/92)).
The following are deprecated but do not yet emit warnings:
- `calendar.event_by_uid()` - use `calendar.get_event_by_uid()` instead
- `calendar.todo_by_uid()` - use `calendar.get_todo_by_uid()` instead
- `calendar.journal_by_uid()` - use `calendar.get_journal_by_uid()`
instead
- `calendar.object_by_uid()` - use `calendar.get_object_by_uid()`
instead
- `principal.calendars()` - use `principal.get_calendars()` instead
- `calendar.events()` - use `calendar.get_events()` instead
- `calendar.todos()` - use `calendar.get_todos()` instead
- `calendar.journals()` - use `calendar.get_journals()` instead
- `calendar.objects_by_sync_token()` - use
`calendar.get_objects_by_sync_token()` instead
The following `check_*_support()` methods are deprecated but do not yet
emit warnings:
- `client.check_dav_support()` - use `client.supports_dav()` instead
- `client.check_cdav_support()` - use `client.supports_caldav()` instead
- `client.check_scheduling_support()` - use
`client.supports_scheduling()` instead
(Those methods actively probe the server; `is_supported()` is a
configuration lookup.)
Additionally, direct `DAVClient()` instantiation should migrate to
`get_davclient()` factory method (see
`docs/design/API_NAMING_CONVENTIONS.md`)
##### Added
- Experimental **JMAP calendar client** — new `caldav.jmap` package
providing a JMAP client
for servers implementing RFC 8620 (JMAP Core) and RFC 8984 (JMAP
Calendars).
Features:
- Synchronous `JMAPClient` and asynchronous `AsyncJMAPClient` with
mirrored APIs
- Full calendar + event CRUD (`create_event`, `get_event`,
`update_event`,
`delete_event`, `search_events`)
- Incremental sync via `get_sync_token` / `get_objects_by_sync_token`
- Task CRUD (draft-ietf-jmap-tasks) via `create_task`, `get_task`,
`update_task`, `delete_task`
- Bidirectional iCalendar ↔ JSCalendar conversion layer
- `get_jmap_client()` factory reads from the same config sources as
`get_davclient()` (env vars, config file)
- Tested against Cyrus IMAP
- **Full async API** - New `AsyncDAVClient` and async-compatible domain
objects:
```python
from caldav.async_davclient import get_davclient
async with await get_davclient(url="...", username="...",
password="...") as client:
principal = await client.get_principal()
calendars = await client.get_calendars()
for cal in calendars:
events = await cal.get_events()
```
- **Retry-After / rate-limit handling** (RFC 6585 / RFC 9110) --
`DAVClient` and `AsyncDAVClient` now expose `rate_limit_handle`,
`rate_limit_default_sleep`, and `rate_limit_max_sleep` parameters (this
may be specified in the configuration file as well). When
`rate_limit_handle=True` the client automatically sleeps and retries on
429 Too Many Requests and 503 Service Unavailable responses that include
a `Retry-After` header. When `rate_limit_handle=False` (default) a
`RateLimitError` is raised immediately so callers can implement their
own back-off strategy. New `caldav.lib.error.RateLimitError` has
`retry_after` (raw header string) and `retry_after_seconds` (parsed
float) attributes.
[#​627](https://redirect.github.com/python-caldav/caldav/issues/627)
- **`search.is-not-defined.category` and `search.is-not-defined.dtend`**
-- new client-side workaround sub-features for servers that do not
support the `CALDAV:is-not-defined` filter natively for these
properties.
- **Base+override feature profiles** -- YAML config now supports
inheriting from a base profile:
```yaml
my-server:
features:
base: nextcloud
search.comp-type: unsupported
```
- **Compatibility fixes**
- New feature flags
- `save-load.event.recurrences.exception` which is supported if the
server stores master+exception VEVENTs as a single calendar object as
per the RFC. Stalwart splits them into separate objects. Stalwart
recombines the data when doing an expanded search, so `expand=True`
searches now automatically fall back to server-side `CALDAV:expand`.
(Arguably, `unsupported` here could also mean the exception data was
simply discarded. If needed, I'll refine this in a future version)
- `save-load.journal.mixed-calendar` - some calendar servers offers a
separate journal list.
- `save-load.reuse-deleted-uid` - server allows immediate reuse of an
uid if the old object has been deleted
- `search.time-range.*.old-dates` - test data mostly have historic
dates. Calendars are primarily made for future happenings. Some calendar
servers does not support searching for things that happened 20 years
ago, even for a very small calendar.
- `search.is-not-defined.category` and `search.is-not-defined.dtend` -
actually, those are artifacts. The bug was on the client side, not
server side. I may delete them in a future release.
- Fallback for missing calendar-home-set -- client now falls back to the
principal URL when `calendar-home-set` property is not available (e.g.
GMX).
- Load fallback for changed URLs -- `CalendarObjectResource.load()` now
falls back to UID-based lookup when servers change object URLs after a
save.
- Many other tweaks and fixings of the compatibility hints.
- Added python-dateutil and PyYAML as explicit dependencies (were
transitive)
- Quite some methods have been renamed for consistency and to follow
best current practices. See the Deprecated section.
- `Calendar` class now accepts a `name` parameter in its constructor,
addressing a long-standing API inconsistency
([#​128](https://redirect.github.com/python-caldav/caldav/issues/128))
- **CalendarObjectResource.id property** - Returns the UID of calendar
objects
([#​515](https://redirect.github.com/python-caldav/caldav/issues/515))
- **calendar.searcher() API** - Factory method for advanced search
queries
([#​590](https://redirect.github.com/python-caldav/caldav/issues/590)):
```python
searcher = calendar.searcher()
searcher.add_filter(...)
results = searcher.search()
``
```
- Improved API for accessing the `CalendarObjectResource` properties
([#​613](https://redirect.github.com/python-caldav/caldav/issues/613)
):
- `get_data()`, `get_icalendar_instance`, `get_vobject_instance`,
`get_icalendar_component`:
- Returns COPIES of the data
- `edit_*` (but no `edit_data` - the data is an immutable string, should
use simply `object.data = foo` for editing it)
- Returns a context manager
- "Borowing pattern" - `with obj.get_foo`, the client may edit foo, and
then `obj.save()` to send it to the server.
##### Fixed
- RFC 4791 compliance: Don't send Depth header for calendar-multiget
REPORT (clients SHOULD NOT send it, but servers MUST ignore it per §7.9)
- Lots of minor fixes and workarounds were done while trying to run the
integration tests for v3.0, most of them fixing new bugs introduced in
the development branch, but also new workarounds for server
incompatibilities (and better fixing of old workarounds). v3.0 was
tested on quite many more servers than v2.2.6.
- Possibly other minor bugfixes adressing old previously unknown bugs -
frankly, I've lost the overview. v3.0 has a lot of code changes.
- The `is-not-defined` filter for CATEGORIES did not work, and for DTEND
it did not work for full day events. (this was fixes in the
`icalendar-searcher`, version 1.0.5).
##### Changed
- Optimilizations on data conversions in the `CalendarObjectResource`
properties
([#​613](https://redirect.github.com/python-caldav/caldav/issues/613)
)
- Lazy imports (PEP 562) -- `import caldav` is now significantly faster.
Heavy dependencies (lxml, niquests, icalendar) are deferred until first
use.
[#​621](https://redirect.github.com/python-caldav/caldav/issues/621)
- Search refactored to use generator-based Sans-I/O pattern --
`_search_impl` yields `(SearchAction, data)` tuples consumed by sync or
async wrappers
- Configuration system expanded: `get_connection_params()` provides
unified config discovery with clear priority (explicit params > test
server config > env vars > config file)
- `${VAR}` and `${VAR:-default}` environment variable expansion in
config values
- Test configuration migrated from legacy `tests/conf.py` to new
`tests/test_servers/` framework
- Lots of refactored code.
- "Black Style" replaced with ruff
- Compatibility hint matrix has been updated a bit. I'm a bit confused
on weather it's due to changes in my caldav-server-tester tool, changed
behaviour in newer versions of the servers, or other reasons. Running
the integration tests and debugging such issues takes a lot of time and
effort.
##### Security
- UUID1 usage in UID generation may embed the host MAC address in
calendar UIDs. Since calendar events are shared with third parties, this
may be a privacy concern. A switch to UUID4 has been made some places in
the code. (Running a grep just when doing the final touches on the
CHANGELOG, I discovered that there is still some UUID1-instances left.
It should be safe to change it, but I don't want to delay the release of
v3.0.0, so it will have to go into a future v3.0.1 release)
##### Test Framework
- **New Docker test servers**:
- Apple Calendar Server (CCS) - the project was discontinued long ago,
but used to be a flagship of compatibility - and I suspect the iCloud
server has inheritated some code from this project.
- DAViCal - an old server, but maintained and one of the more
standard-compliant servers. It also has multi-user support.
- Davis - it's a relative of Baikal
- Stalwart - a quite new project, mail+calendar, supports JMAP and is
funded through NLNet
- Zimbra - multi-user mail+calendar. Financed through having a non-free
"enterprise" version with paid licenses.
- Fixed Nextcloud Docker test server tmpfs permissions race condition
- Added deptry for dependency verification in CI
- The test server framework has been refactored with a new
`tests/test_servers/` module. It provides **YAML-based server
configuration**: see `tests/test_servers/__init__.py` for usage
- Added pytest-asyncio for async test support
- **Updated Docker configs**: Baikal, Cyrus, Nextcloud, SOGo
- Added lychee link-check workflow
- Added `convert_conf_private.py` migration tool for legacy config
format
- New test files: `test_lazy_import.py`; expanded
`test_async_davclient.py`, `test_async_integration.py`,
`test_compatibility_hints.py`, `test_search.py`, `test_caldav_unit.py`
- Added async rate-limit unit tests matching the sync test suite
- caldav-server-tester: `CheckRecurrenceSearch` now also verifies
implicit recurrence support for all-day (VALUE=DATE) recurring events,
marking the feature as `fragile` (with behaviour description) when only
datetime recurring events work.
##### GitHub Pull Requests Merged
-
[#​607](https://redirect.github.com/python-caldav/caldav/issues/607)
- Add deptry for dependency verification (also in 2.2.6) -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​610](https://redirect.github.com/python-caldav/caldav/issues/610)
- Development for the v3.0-branch - async support and misc -- Tobias
Brox ([@​tobixen](https://redirect.github.com/tobixen))
-
[#​617](https://redirect.github.com/python-caldav/caldav/issues/617)
- Refactoring the `calendar.search` -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​618](https://redirect.github.com/python-caldav/caldav/issues/618)
- Deprecate DAVObject.name in favor of `get_display_name()` -- Tobias
Brox ([@​tobixen](https://redirect.github.com/tobixen))
-
[#​622](https://redirect.github.com/python-caldav/caldav/issues/622)
- Fix overlong inline literal, replace hyphens with en-dashes --
[@​joshinils](https://redirect.github.com/joshinils)
-
[#​623](https://redirect.github.com/python-caldav/caldav/issues/623)
- More v3.0 development -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​625](https://redirect.github.com/python-caldav/caldav/issues/625)
- feat(jmap): add caldav/jmap — JMAP calendar and task client -- Sashank
Bhamidi
([@​SashankBhamidi](https://redirect.github.com/SashankBhamidi))
-
[#​626](https://redirect.github.com/python-caldav/caldav/issues/626)
- docs(jmap): JMAP usage documentation and autodoc stubs -- Sashank
Bhamidi
([@​SashankBhamidi](https://redirect.github.com/SashankBhamidi))
-
[#​630](https://redirect.github.com/python-caldav/caldav/issues/630)
- More v3.0 development -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
##### GitHub Pull Requests Closed (not merged)
-
[#​565](https://redirect.github.com/python-caldav/caldav/issues/565)
- ADR: HTTPX Async-First Architecture with Thin Sync Wrappers (design
exploration; superceded by
[#​610](https://redirect.github.com/python-caldav/caldav/issues/610))
-- Chris Coutinho
([@​cbcoutinho](https://redirect.github.com/cbcoutinho))
-
[#​588](https://redirect.github.com/python-caldav/caldav/issues/588)
- Fix duplicate parameter bug in search() recursive call (superseded by
search refactoring in
[#​617](https://redirect.github.com/python-caldav/caldav/issues/617))
-- Tobias Brox ([@​tobixen](https://redirect.github.com/tobixen))
-
[#​603](https://redirect.github.com/python-caldav/caldav/issues/603)
- Playground/new async api design (exploratory work, superceded by
[#​610](https://redirect.github.com/python-caldav/caldav/issues/610))
-- Tobias Brox ([@​tobixen](https://redirect.github.com/tobixen))
-
[#​604](https://redirect.github.com/python-caldav/caldav/issues/604)
- mistake, pull request created from the wrong branch -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​628](https://redirect.github.com/python-caldav/caldav/issues/628)
- ISSUE-627: Add handling of Retry-After header for 429 and 503 status
codes (code incorporated into master) -- Tema
([@​temsocial](https://redirect.github.com/temsocial))
##### GitHub Issues Closed
-
[#​71](https://redirect.github.com/python-caldav/caldav/issues/71)
- `add_object` vs `save_object` (reopened, reverted and closed)
-
[#​128](https://redirect.github.com/python-caldav/caldav/issues/128)
- Calendar constructor should accept name parameter (long-standing
issue) -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​342](https://redirect.github.com/python-caldav/caldav/issues/342)
- need support asyncio --
[@​ArtemIsmagilov](https://redirect.github.com/ArtemIsmagilov)
-
[#​424](https://redirect.github.com/python-caldav/caldav/issues/424)
- implement support for JMAP protocol --
[@​ArtemIsmagilov](https://redirect.github.com/ArtemIsmagilov)
-
[#​457](https://redirect.github.com/python-caldav/caldav/issues/457)
- Replace requests with niquests or httpx? -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​509](https://redirect.github.com/python-caldav/caldav/issues/509)
- Refactor the test configuration again -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​515](https://redirect.github.com/python-caldav/caldav/issues/515)
- CalendarObjectResource.id property returns UID -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​518](https://redirect.github.com/python-caldav/caldav/issues/518)
- Test setup: try to mute expected error/warning logging -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​580](https://redirect.github.com/python-caldav/caldav/issues/580)
- search.py is already ripe for refactoring -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​589](https://redirect.github.com/python-caldav/caldav/issues/589)
- Replace "black style" with ruff -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​590](https://redirect.github.com/python-caldav/caldav/issues/590)
- calendar.searcher() API for advanced search queries -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​601](https://redirect.github.com/python-caldav/caldav/issues/601)
- `get_davclient` to be importable from caldav -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​609](https://redirect.github.com/python-caldav/caldav/issues/609)
- How to get original RRULE when search expand=True? -- JS Moore
([@​jakkarth](https://redirect.github.com/jakkarth))
-
[#​613](https://redirect.github.com/python-caldav/caldav/issues/613)
- Data representation API for efficient data access -- Tobias Brox
([@​tobixen](https://redirect.github.com/tobixen))
-
[#​621](https://redirect.github.com/python-caldav/caldav/issues/621)
- Using niquests makes import unreasonably slow --
[@​rymdbar](https://redirect.github.com/rymdbar)
-
[#​627](https://redirect.github.com/python-caldav/caldav/issues/627)
- Rate-limit / Retry-After handling -- Tema
([@​temsocial](https://redirect.github.com/temsocial))
-
[#​631](https://redirect.github.com/python-caldav/caldav/issues/631)
- Cannot create calendar event by AsyncDAVClient (fix implemented,
pending user confirmation) -- Oleg Yurchik
([@​OlegYurchik](https://redirect.github.com/OlegYurchik))
##### Credits
The following people contributed to this release through issue reports,
pull requests, and/or commits:
- [@​ArtemIsmagilov](https://redirect.github.com/ArtemIsmagilov)
- Chris Coutinho
([@​cbcoutinho](https://redirect.github.com/cbcoutinho))
- [@​joshinils](https://redirect.github.com/joshinils)
- JS Moore ([@​jakkarth](https://redirect.github.com/jakkarth))
- Oleg Yurchik
([@​OlegYurchik](https://redirect.github.com/OlegYurchik))
- [@​rymdbar](https://redirect.github.com/rymdbar)
- Sashank Bhamidi
([@​SashankBhamidi](https://redirect.github.com/SashankBhamidi))
- Tema ([@​temsocial](https://redirect.github.com/temsocial))
- Tobias Brox ([@​tobixen](https://redirect.github.com/tobixen))
##### Time Spent
Since the 2.2.1-release and excluding the JMAP-work done by Sashank,
Tobias has spent around 132 hours on this project.
In the 3.0-release, AI-tools have been used for improving quality and
speed. My first impression was very good. It seemed like the AI
understood the project, and it could fix things faster and better than
what I could do myself - I really didn't expect it to create any good
code at all. Well, sometimes it does, other times not. Soon enough I
also learned that the AI is good at creating crap code, breaking
things and Claude is particularly good at duplicating code and code
paths. In the end, despite using Claude I've spent more time on this
release than what I had estimated. However, I believe I've done a
quite through work on preserving backward-compatibility while also
developing a better API.
From my roadmap, those are the estimates:
- [x] 50 hours for ASync + improved API - fully done
- [x] 23 hours for fixing/closing old issues - fully done
- [ ] 12 hours for documentation - partly done
- [ ] 40 hours for fixing/closing issues related with scheduling in 3.2
- done the davical test server, estimated to take 6 hours.
In addition, lots of time spent on things that aren't covered by the
roadmap:
- The caldav-server-tester utility (but none of it into "polishing and
releasing" as the roadmap says)
- More docker test servers
- Responding fast to inbound issues and pull requests
- Communication and collaboration
- The release itself (running tests towards lots of servers with quirks
- like having to wait for several minutes from an event is edited until
it can be found through a search operation - looking through and making
sure the CHANGELOG is complete, etc) is quite tedious and easily takes
several days - weeks if it's needed to tweak on workarounds and
compatbility hints to get the tests passing.
#### \[2.2.6] - 2026-02-01
##### Fixed
- Fixed potential IndexError in URL path joining when path is empty
- Fixed NameError in search.py caused by missing import of `logging`
module, which was masking actual errors when handling malformed
iCalendar data.
[#​614](https://redirect.github.com/python-caldav/caldav/issues/614)
##### Changed
- Updated example files to use the recommended `get_davclient()` factory
function instead of `DAVClient()` directly
##### Test Framework
- Added deptry for dependency verification in CI
##### GitHub Pull Requests Merged
-
[#​607](https://redirect.github.com/python-caldav/caldav/issues/607)
- Add deptry for dependency verification
-
[#​605](https://redirect.github.com/python-caldav/caldav/issues/605)
- Update examples to use get\_davclient() instead of DAVClient()
##### GitHub Issues Closed
-
[#​612](https://redirect.github.com/python-caldav/caldav/issues/612)
- Export get\_davclient from caldav package
-
[#​614](https://redirect.github.com/python-caldav/caldav/issues/614)
- Missing import logging in search.py causes NameError masking actual
errors
(2.2.4 is without niquests in the dependencies. 2.2.5 is with niquests.
2.2.6 is with niquests and a tiny CHANGELOG-fix)
##### Added
- `get_davclient` is now exported from the `caldav` package, allowing
`from caldav import get_davclient`.
[#​612](https://redirect.github.com/python-caldav/caldav/issues/612)
#### \[2.2.3] - 2025-12-06]
##### Fixed
- Some servers did not support the combination of HTTP/2-multiplexing
and authentication. Two workarounds fixed; baikal will specifically not
use multiplexing, and an attempt to authenticate without multiplexing
will be made upon authentication problems. Fixes
[#​564](https://redirect.github.com/python-caldav/caldav/issues/564)
- The DTSTAMP is mandatory in icalendar data. The `vcal.fix`-scrubber
has been updated to make up a DTSTAMP if it's missing. Fixes
[#​504](https://redirect.github.com/python-caldav/caldav/issues/504)
#### \[2.2.2] - 2025-12-04]
2.2.1 is released with requests support (mispelled riquests in 2.2.0),
2.2.2 with niquests support
#### \[2.2.1] - \[2025-12-04]
Highlights:
- New ways to set up client connections:
- For cloud-based services, it should suffice to pass username, password
and the name of the service, no URL needed (though, just some few
providers supported so far)
- If the username is in email format, then it's generally not needed to
pass a URL.
- v2.2 comes with lots of workarounds around lack of feature support in
the servers - notably the sync-token API will work also towards servers
not supporting sync-tokens. In some cases lack of server functionality
is detected, but as for now it may be needed to specify what server one
is user through the `features` configuration flag.
- v2.2 supports more complex searches. Client-side filtering will be
utilized for the things that aren't supported on the server side.
##### Potentially Breaking Changes
(More information on the changes in the Changed section)
- **Search results may differ** due to workarounds for various server
compatibility problems. For some use cases this may be a breaking
change. <https://xkcd.com/1172/>
- **New dependencies**. As far as I understand the SemVer standard, new
dependencies can be added without increasing the major version number -
but for some scenarios where it's hard to add new dependencies, this may
be a breaking change.
- The python-dns package is used for RFC6764 discovery. This is a
well-known package, so the security impact should be low. This library
is only used when doing such a recovery. If anyone minds this
dependency, I can change the project so this becomes an optional
dependency.
- Some code has been split out into a new package -
`icalendar-searcher`. so this may also break if you manage the
dependencies manually. As this package was made by the maintainer of the
CalDAV package, the security impact of adding this dependency should be
low.
- Potentially major **performance problems**: rather than throwing
errors, the sync-token-API may now fetch the full calendar. This change
is intended to be un-breaking, but for people having very big calendars
and syncing them to a mobile device with limited memory, bandwidth, CPU
and battery, this change may be painful. (If a servers is marked to have
"fragile" support for sync-tokens, the fallback will apply to those
servers too).
- **Very slow test suite** due to lots of docker-containers spun up with
verious server implementations. See the "Test Suite" section below.
##### Changed
- Transparent handling of calendar servers not supporting sync-tokens.
The API will yield the same result, albeit with more bandwidth and
memory consumption.
- I'm still working on "compatibility hints". Unfortunately,
documentation is still missing.
- **Major refactoring!** Some of the logic has been pushed out of the
CalDAV package and into a new package, icalendar-searcher. New logic for
doing client-side filtering of search results have also been added to
that package. This refactoring enables possibilities for more advanced
search queries as well as client-side filtering.
- For advanced search queries, it's needed to create a
`caldav.CalDAVSearcher` object, add filters and do a
`searcher.search(cal)` instead of doing `cal.search(...)`.
- **Server compatibility improvements**: Significant work-arounds added
for inconsistent CalDAV server behavior, aiming for consistent search
results regardless of the server in use. Many of these work-arounds
require proper server compatibility configuration via the `features` /
`compatibility_hints` system. This may be a **breaking change** for some
use cases, as backward-bug-compatibility is not preserved - searches may
return different results if the previous behavior was relying on server
quirks.
##### Fixed
- As noted above, quite some changes have been done to searches. One may
argue if this is breaking changes, changes or bugfixes. At least github
issues
[#​434](https://redirect.github.com/python-caldav/caldav/issues/434),
[#​461](https://redirect.github.com/python-caldav/caldav/issues/461),
[#​566](https://redirect.github.com/python-caldav/caldav/issues/566)
and
[#​509](https://redirect.github.com/python-caldav/caldav/issues/509)
has been closed in the process.
- A minor bug in the FeatureSet constructor was fixed, sometimes
information could be lost.
- Downgraded a CRITICAL error message to INFO, for some conditions that
clearly wasn't CRITICAL (HTML error responses from server or wrong
content-type given, when XML was expected)
- Probably some other minor bug fixes (though, most of the bugs fixed in
this release was introduced after 2.1.2)
- A user managed to trigger a crash bug in the search in
[#​587](https://redirect.github.com/python-caldav/caldav/issues/587)
- this has indirectly been fixed through the refactorings.
##### Added
- **New ways to configure the client connection, new parameters**
- **RFC 6764 DNS-based service discovery**: Automatic CalDAV/CardDAV
service discovery using DNS SRV/TXT records and well-known URIs. Users
can now provide just a domain name or email address (e.g.,
`DAVClient(username='user@example.com')`) and the library will
automatically discover the CalDAV service endpoint. The discovery
process follows RFC 6764 specification. This involves a new required
dependency: `dnspython` for DNS queries. DNS-based discovery can be
disabled in the davclient connection settings, but I've opted against
implementing a fallback if the dns library is not installed.
- Use `features: posteo` instead of `url: https://posteo.de:8443/` in
the connection configuration.
- Use `features: nextcloud` and `url: my.nextcloud.provider.eu` instead
of `url: https://my.nextcloud.provider.eu/remote.php/dav`
- Or even easier, use `features: nextcloud` and `username:
tobixen@example.com`
- New `require_tls` parameter (default: `True`) prevents DNS-based
downgrade attacks
- The client connection parameter `features` may now simply be a string
label referencing a well-known server or cloud solution - like
`features: posteo`.
[#​561](https://redirect.github.com/python-caldav/caldav/pull/561)
- The client connection parameter `url` is no longer needed when
referencing a well-known cloud solution.
[#​561](https://redirect.github.com/python-caldav/caldav/pull/561)
* The client connection parameter `url` may contain just the domain name
(without any slashes). It may then either look up the URL path in the
known caldav server database, or through RFC6764
- **New interface for searches** `mysearcher =
caldav.CalDAVSearcher(...) ; mysearcher.add_property_filter(...) ;
mysearcher.search(calendar)`. It's a bit harder to use, but opens up the
possibility to do more complicated searches.
- **Collation support for CalDAV text-match queries (RFC 4791 §
9.7.5)**: CalDAV searches may now pass different collation attributes to
the server, enabling case-insensitive searches. (but more work on this
may be useful, see
[#​567](https://redirect.github.com/python-caldav/caldav/issues/567)).
The `CalDAVSearcher.add_property_filter()` method now accepts
`case_sensitive` and `collation` parameters. Supported collations
include:
- `i;octet` (case-sensitive, binary comparison) - default
- `i;ascii-casemap` (case-insensitive for ASCII characters, RFC 4790)
- `i;unicode-casemap` (Unicode case-insensitive, RFC 5051 - server
support may vary)
- Client-side filtering method: `CalDAVSearcher.filter()` provides
comprehensive client-side filtering, expansion, and sorting of calendar
objects with full timezone preservation support.
- Example code: New `examples/collation_usage.py` demonstrates
case-sensitive and case-insensitive calendar searches.
##### Security
There is a major security flaw with the RFC6764 discovery. If the DNS is
not trusted (public hotspot, for instance), someone can highjack the
connection by spoofing the service records. The protocol also allows to
downgrade from https to http. Utilizing this it may be possible to steal
the credentials. Mitigations:
- DNSSEC is the ultimate soluion, but DNSSEC is not widely used. I tried
implementing robust DNSSEC validation, but it was too complicated.
- Require TLS. By default, connections through the autodiscovery is
required to use TLS.
- Decline domain change. If acme.com forwards to caldav.acme.com, it
will be accepted, if it forward to evil.hackers.are.us the connection is
declined.
Also, the RFC6764 discovery may not always be robust, causing fallbacks
and hence a non-deterministic behaviour.
##### Deprecated
- `Event.expand_rrule` will be removed in some future release, unless
someone protests.
- `Event.split_expanded` too. Both of them were used internally, now
it's not. It's dead code, most likely nobody and nothing is using them.
##### GitHub Issues Closed
-
[#​574](https://redirect.github.com/python-caldav/caldav/issues/574)
- SECURITY: check domain name on auto-discovery (2025-11-29) -
[#​574](https://redirect.github.com/python-caldav/caldav/issues/574)
- fixes issues introduced after previous release
-
[#​532](https://redirect.github.com/python-caldav/caldav/issues/532)
- Replace compatibility flags list with compatibility matrix dict
(2025-11-10)
[#​532](https://redirect.github.com/python-caldav/caldav/issues/532)
- this process is not completely done, a new issue has been raised for
mopping up the rest
-
[#​402](https://redirect.github.com/python-caldav/caldav/issues/402)
- Server compatibility hints (2025-12-03)
[#​402](https://redirect.github.com/python-caldav/caldav/issues/402)
- sort of duplicate of
[#​532](https://redirect.github.com/python-caldav/caldav/issues/532)
-
[#​463](https://redirect.github.com/python-caldav/caldav/issues/463)
- Try out paths to find caldav base URL (2025-11-10)
[#​463](https://redirect.github.com/python-caldav/caldav/issues/463)
- sort of solved through the compatbility hints file.
-
[#​461](https://redirect.github.com/python-caldav/caldav/issues/461)
- Path handling error with non-standard URL formats (2025-12-02)
[#​461](https://redirect.github.com/python-caldav/caldav/issues/461)
- the issue ended up identifying the need to work around missing
server-side support for sync-token, this has been fixed
-
[#​434](https://redirect.github.com/python-caldav/caldav/issues/434)
- Search event with summary (2025-11-27)
[#​434](https://redirect.github.com/python-caldav/caldav/issues/434)
- the new search interface contains work-arounds for server-side
incompatibilities as well as advanced client-side filtering
-
[#​401](https://redirect.github.com/python-caldav/caldav/issues/401)
- Some server needs explicit event or task when doing search
(2025-07-19)
[#​401](https://redirect.github.com/python-caldav/caldav/issues/401)
- code now contains clean workarounds for fetching everything regardless
of server side support
-
[#​102](https://redirect.github.com/python-caldav/caldav/issues/102)
- Support for RFC6764 - find CalDAV URL through DNS lookup (created
2020, closed 2025-11-27) -
[#​102](https://redirect.github.com/python-caldav/caldav/issues/102)
-
[#​311](https://redirect.github.com/python-caldav/caldav/issues/311)
- Google calendar - make authentication simpler and document it (created
2023, closed 2025-06-16) -
[#​311](https://redirect.github.com/python-caldav/caldav/issues/311)
- no work on Google has been done, but user-contributed examples and
documentation has been refactored, polished and published.
-
[#​372](https://redirect.github.com/python-caldav/caldav/issues/372)
- Server says "Forbidden" when creating event with timezone (created
2024, closed 2025-12-03) -
[#​372](https://redirect.github.com/python-caldav/caldav/issues/372)
- it's outside the scope supporting the old dateutil.tz objects in the
CalDAV library. Checks have been added to the caldav-server-checker
script to verify that the new-style Timezone objects work.
-
[#​351](https://redirect.github.com/python-caldav/caldav/issues/351)
- `calendar.search`-method with timestamp filters yielding too much
(created 2023, closed 2025-12-02) -
[#​351](https://redirect.github.com/python-caldav/caldav/issues/351)
the new search interface may do client-side filtering
-
[#​340](https://redirect.github.com/python-caldav/caldav/issues/340)
- 507 error during collection sync (created 2023, closed 2025-12-03) -
[#​340](https://redirect.github.com/python-caldav/caldav/issues/340)
- this should be fixed by the new sync-tokens workaround
-
[#​587](https://redirect.github.com/python-caldav/caldav/issues/587)
- Calendar.search broken with TypeError: Calendar.search() got multiple
values for argument 'sort\_keys' (created 2025-12-04, closed 2025-12-04)
-
[#​587](https://redirect.github.com/python-caldav/caldav/issues/587)
- this bug has indirectly been fixed through the refactorings.
##### GitHub Pull Requests Merged
-
[#​584](https://redirect.github.com/python-caldav/caldav/issues/584)
- Bedework server support (2025-12-04) -
[#​584](https://redirect.github.com/python-caldav/caldav/pull/584)
-
[#​583](https://redirect.github.com/python-caldav/caldav/issues/583)
- Transparent fallback for servers not supporting sync tokens
(2025-12-02) -
[#​583](https://redirect.github.com/python-caldav/caldav/pull/583)
-
[#​582](https://redirect.github.com/python-caldav/caldav/issues/582)
- Fix docstrings in Principal and Calendar classes (2025-12-02) -
[#​582](https://redirect.github.com/python-caldav/caldav/pull/582)
-
[#​581](https://redirect.github.com/python-caldav/caldav/issues/581)
- SOGo server support (2025-12-02) -
[#​581](https://redirect.github.com/python-caldav/caldav/pull/581)
-
[#​579](https://redirect.github.com/python-caldav/caldav/issues/579)
- Sync-tokens compatibility feature flags (2025-11-29) -
[#​579](https://redirect.github.com/python-caldav/caldav/pull/579)
-
[#​578](https://redirect.github.com/python-caldav/caldav/issues/578)
- Docker server testing cyrus (2025-12-02) -
[#​578](https://redirect.github.com/python-caldav/caldav/pull/578)
-
[#​576](https://redirect.github.com/python-caldav/caldav/issues/576)
- Add RFC 6764 domain validation to prevent DNS hijacking attacks
(2025-11-29) -
[#​576](https://redirect.github.com/python-caldav/caldav/pull/576)
-
[#​575](https://redirect.github.com/python-caldav/caldav/issues/575)
- Add automated Nextcloud CalDAV/CardDAV testing framework (2025-11-29)
-
[#​575](https://redirect.github.com/python-caldav/caldav/pull/575)
-
[#​573](https://redirect.github.com/python-caldav/caldav/issues/573)
- Add Baikal Docker test server framework for CI/CD (2025-11-28) -
[#​573](https://redirect.github.com/python-caldav/caldav/pull/573)
-
[#​570](https://redirect.github.com/python-caldav/caldav/issues/570)
- Add RFC 6764 DNS-based service discovery (2025-11-27) -
[#​570](https://redirect.github.com/python-caldav/caldav/pull/570)
-
[#​569](https://redirect.github.com/python-caldav/caldav/issues/569)
- Improved substring search (2025-11-27) -
[#​569](https://redirect.github.com/python-caldav/caldav/pull/569)
-
[#​566](https://redirect.github.com/python-caldav/caldav/issues/566)
- More compatibility work (2025-11-27) -
[#​566](https://redirect.github.com/python-caldav/caldav/pull/566)
-
[#​563](https://redirect.github.com/python-caldav/caldav/issues/563)
- Refactoring search and filters (2025-11-19) -
[#​563](https://redirect.github.com/python-caldav/caldav/pull/563)
-
[#​561](https://redirect.github.com/python-caldav/caldav/issues/561)
- Connection details in the server hints (2025-11-10) -
[#​561](https://redirect.github.com/python-caldav/caldav/pull/561)
-
[#​560](https://redirect.github.com/python-caldav/caldav/issues/560)
- Python 3.14 support (2025-11-09) -
[#​560](https://redirect.github.com/python-caldav/caldav/pull/560)
##### Test Framework
- **Automated Docker testing framework** using Docker containers, if
docker is available.
- Cyrus, NextCloud and Baikal added so far.
- For all of those, automated setups with a well-known username/password
combo was a challenge. I had planned to add more servers, but this
proved to be too much work.
- The good thing is that test coverage is increased a lot for every pull
request, I hope this will relieving me of a lot of pain learning that
the tests fails towards real-world servers when trying to do a release.
- The bad thing is that the test runs takes a lot more time. Use `pytest
-k Radicale` or `pytest -k Xandikos` - or run the tests in an
environment not having access to docker if you want a quicker test run -
or set up a local `conf_private.py` where you specify what servers to
test. It may also be a good idea to run `start.sh` and `stop.sh` in
`tests/docker-test-servers/*` manually so the container can stay up for
the whole duration of the testing rather than being taken up and down
for every test.
- **Docker volume cleanup**: All teardown functions should automatically
prune ephemeral Docker volumes to prevent `/var/lib/docker/volumes` from
filling up with leftover test data. This applies to Cyrus, Nextcloud,
and Baikal test servers.
- Since the new search code now can work around different server quirks,
quite some of the test code has been simplified. Many cases of "make a
search, if server supports this, then assert correct number of events
returned" could be collapsed to "make a search, then assert correct
number of events returned" - meaning that **the library is tested rather
than the server**.
- Some of the old "compatibility\_flags" that is used by the test code
has been moved into the new "features"-structure in
`caldav/compatibility_hints.py`. Use the package caldav-server-checker
to check the feature-set of your CalDAV server (though, as for now the
last work done is on a separate branch. A relase will be made soon).
- Note, the `testCheckCompatibility` will be run if and only if the
caldav-server-checker package is installed and available. If the package
is installed, the version of it has to correspond exactly to the caldav
version - and even then, it may break for various reasons (the caldav
server tester is still under development, no stable release exists yet).
The corresponding version of the package has not been released yet (it's
even not merged to the main branch). I hope to improve on this somehow
before the next release. It can be a very useful test - if the
compatibility configuration is wrong, tests may break or be skipped for
the wrong reasons.
##### Time Spent
(The "Time Spent"-section was missing from the 2.1-release, so this
includes everything since 2.0)
The maintainer has spent around 230 hours since version 2.0.0, plus paid
some money for AI-assistance from Claude. This time includes work on the
two sub-projects icalendar-searcher and caldav-server-tester (not
released yet).
The estimation given at the road map was 28h for "Server checker and
server compatibility hints project", 8h for "Maintain and expand the
test server list", and 12h for "Outstanding issues slated for v3.0".
Including the Claude efforts, consider this to be 5x as much time as
estimated.
Some few reasons of the overrun:
- Quite much of this time has been put down into the
caldav-server-tester project, and the icalendar-search project also took
me a few days to complete.
- "Let's make sure to support both case-sensitive and case-insensitive
search" may sound like a simple task, but collations is a major tarpit!
Now I know that the correct uppercase version of "istanbul" depends on
the locale used ...
- The test framework with docker contained servers was also a major
tarpit. "Why not just spin up server X in a docker container" - it
sounded trivial, but then come the hard realites:
- Most of the servers needs some extra configuration to get a test user
with well-known username and password in place
- Some servers are optimized for manual "installation and
configuration", rather than automated setup with an epheremal disk
volume.
- Some servers have external requirements, like a stand-alone database
server, requiring significant amounts of configuration for connecting
the database and the calendar server (database username, password,
connection details, +++)
- Docker services in the "GitHub Actions" that I use for automated
external testing has to be set up completely different and independently
from the local tests. This is also a tarpit as I cannot inspect and
debug problems so easily, every test run takes very long time and
generates several megabytes of logs.
- Luckily, with the new caldav-server-tester script it's easy to get the
compatibility configuration readily set up. In theory. In practice, I
need to do quite some work on the caldav-server-tester to correctly
verify all the unique quirks of the new server.
- In practice, the test suite will still be breaking, requiring lots of
debugging figuring out of the problems.
- Quite many other rabbit holes and tarpits have been found on the way,
but I digress. This is quite a bit
</details>
---
### Configuration
📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/cloud-py-api/nc_py_api).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41Ni4wIiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Review <review@local>1 parent 9692bdd commit 0da4be0
3 files changed
Lines changed: 241 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | | - | |
| 28 | + | |
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
| 66 | + | |
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
10 | 21 | | |
11 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
12 | 25 | | |
13 | 26 | | |
14 | 27 | | |
| |||
24 | 37 | | |
25 | 38 | | |
26 | 39 | | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
0 commit comments