Skip to content

Update iCal exporter#3290

Merged
arkid15r merged 5 commits intovacanza:devfrom
KJhellico:upd-ical
Feb 26, 2026
Merged

Update iCal exporter#3290
arkid15r merged 5 commits intovacanza:devfrom
KJhellico:upd-ical

Conversation

@KJhellico
Copy link
Copy Markdown
Collaborator

Proposed change

Update iCal exporter:

  • holiday category in iCal support (for single-category holidays objects)
  • export to pathlib.Path

Type of change

  • New country/market holidays support (thank you!)
  • Supported country/market holidays update (calendar discrepancy fix, localization)
  • Existing code/documentation/test/process quality improvement (best practice, cleanup, refactoring, optimization)
  • Dependency update (version deprecation/pin/upgrade)
  • Bugfix (non-breaking change which fixes an issue)
  • Breaking change (a code change causing existing functionality to break)
  • New feature (new holidays functionality in general)

Checklist

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 23, 2026

Summary by CodeRabbit

  • New Features
    • Calendar files now include category information for holidays when applicable
    • The save functionality now accepts both file path strings and Path objects for improved flexibility

Walkthrough

Converts ICalExporter._generate_event to an Iterable generator (yields lines) and emits a single-category CATEGORIES: line when applicable; widens save_ics to accept str | Path and uses Path.write_bytes; tests updated to use pathlib.Path and validate category behavior and Path input handling.

Changes

Cohort / File(s) Summary
ICalExporter core
holidays/ical.py
Changed _generate_event return type from list[str] to Iterable[str] and implemented as a generator (yields lines); emit CATEGORIES: when exactly one category (uppercased); widened save_ics signature to accept `str
Tests
tests/test_ical.py
Replaced os.path/os.remove usage with pathlib.Path APIs; added import of HALF_DAY and UNOFFICIAL; added test_save_ics_pathlib_path (compare outputs for str vs Path, ignoring UID lines) and test_holidays_category (verify CATEGORIES when single UNOFFICIAL, absent when combined with HALF_DAY); adjusted reads/writes to use Path methods.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • PPsyrius
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update iCal exporter' clearly summarizes the main change—enhancing the iCal exporter with category support and pathlib.Path export capability.
Description check ✅ Passed The description is well-related to the changeset, detailing the two key improvements: holiday category support for single-category objects and pathlib.Path export support.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
holidays/ical.py (1)

141-176: ⚠️ Potential issue | 🟠 Major

Use RFC 5545 standard CATEGORIES property.
CATEGORY violates RFC 5545 §3.8.1.2, which specifies CATEGORIES as the property name for calendar event categories. Non-compliant readers may silently ignore the output. Update the property name and the corresponding test assertions.

Changes required

holidays/ical.py:

         if len(self.holidays.categories) == 1:
-            yield f"CATEGORY:{next(iter(self.holidays.categories)).upper()}"
+            yield f"CATEGORIES:{next(iter(self.holidays.categories)).upper()}"

tests/test_ical.py (lines 464-476):

     def test_holidays_category(self):
         single_category_holidays = country_holidays(
             "US", years=2024, categories=UNOFFICIAL, language="en_US"
         )
         output = ICalExporter(single_category_holidays).generate()
-        self.assertIn("CATEGORY:UNOFFICIAL", output)
+        self.assertIn("CATEGORIES:UNOFFICIAL", output)
 
         multi_category_holidays = country_holidays(
             "US", years=2024, categories=(HALF_DAY, UNOFFICIAL), language="en_US"
         )
         output = ICalExporter(multi_category_holidays).generate()
-        self.assertNotIn("CATEGORY:HALF_DAY", output)
-        self.assertNotIn("CATEGORY:UNOFFICIAL", output)
+        self.assertNotIn("CATEGORIES:HALF_DAY", output)
+        self.assertNotIn("CATEGORIES:UNOFFICIAL", output)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@holidays/ical.py` around lines 141 - 176, The VEVENT generator uses the
non-standard PROPERTY name "CATEGORY"; change the property to the RFC
5545-compliant "CATEGORIES" in _generate_event (replace the yield that emits
f"CATEGORY:..." with f"CATEGORIES:...") so single-category events use
"CATEGORIES:<NAME>". Also update the unit tests that assert the old "CATEGORY"
header (tests that reference the literal "CATEGORY" in iCal output) to expect
"CATEGORIES" instead and keep the existing value formatting/uppercasing
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@holidays/ical.py`:
- Around line 141-176: The VEVENT generator uses the non-standard PROPERTY name
"CATEGORY"; change the property to the RFC 5545-compliant "CATEGORIES" in
_generate_event (replace the yield that emits f"CATEGORY:..." with
f"CATEGORIES:...") so single-category events use "CATEGORIES:<NAME>". Also
update the unit tests that assert the old "CATEGORY" header (tests that
reference the literal "CATEGORY" in iCal output) to expect "CATEGORIES" instead
and keep the existing value formatting/uppercasing behavior.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 322a1a3 and 1814ae7.

📒 Files selected for processing (2)
  • holidays/ical.py
  • tests/test_ical.py

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (1694912) to head (6fd12cb).
⚠️ Report is 1 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff            @@
##               dev     #3290   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          307       307           
  Lines        18387     18396    +9     
  Branches      2353      2354    +1     
=========================================
+ Hits         18387     18396    +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

PPsyrius
PPsyrius previously approved these changes Feb 24, 2026
Copy link
Copy Markdown
Collaborator

@PPsyrius PPsyrius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 📆

arkid15r
arkid15r previously approved these changes Feb 25, 2026
@arkid15r arkid15r enabled auto-merge February 25, 2026 23:39
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_ical.py`:
- Around line 413-425: The test reads files using bare open() calls (building
content_1 and content_2) which can leak file descriptors; change both reads to
use context managers (with open(file_path_1) as f: and with open(file_path_2) as
f:) and iterate f.readlines() or the file iterator while filtering out lines
starting with "UID:" so that the file handles are closed immediately after
reading; keep the existing logic that strips line endings and the call to
self.us_exporter.save_ics(file_path=file_path_2).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dae0c8e and 4210101.

📒 Files selected for processing (1)
  • tests/test_ical.py

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_ical.py`:
- Around line 413-427: The comparison in tests/test_ical.py currently filters
only UID lines when building content_1 and content_2, which makes the assertion
flaky due to differing DTSTAMP values; update the list comprehensions that build
content_1 and content_2 (the blocks surrounding file_path_1.read_text() and
file_path_2.read_text() used with self.us_exporter.save_ics) to also skip lines
starting with "DTSTAMP:" so both UID and DTSTAMP are ignored before asserting
equality.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4210101 and 6fd12cb.

📒 Files selected for processing (1)
  • tests/test_ical.py

@arkid15r arkid15r added this pull request to the merge queue Feb 26, 2026
Merged via the queue into vacanza:dev with commit 4a1dcd1 Feb 26, 2026
32 checks passed
@KJhellico KJhellico deleted the upd-ical branch February 26, 2026 15:00
@KJhellico KJhellico mentioned this pull request Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants