Skip to content

Update Germany holidays#3102

Merged
arkid15r merged 2 commits intovacanza:devfrom
KJhellico:upd-germany
Dec 3, 2025
Merged

Update Germany holidays#3102
arkid15r merged 2 commits intovacanza:devfrom
KJhellico:upd-germany

Conversation

@KJhellico
Copy link
Copy Markdown
Collaborator

Proposed change

Update Germany holidays:

  • change start_year to 1991 (first full year after Germany reunification)
  • update Mar 8 holiday name according to laws

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 Dec 2, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Corrected German holiday calendar to start from 1991, removing inaccurate historical 1990 entries across all regions
  • Chores

    • Standardized Women's Day naming convention across all locales
    • Updated translation metadata and version information

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Start year for Germany moved from 1990 to 1991; per-year guards for many holidays were removed so those holidays (and subdivision-specific ones) are always added; "Internationaler Frauentag"/"International Women's Day" was renamed to "Frauentag"/"Women's Day" across code, snapshots, locales, and tests.

Changes

Cohort / File(s) Summary
Core Logic Update
holidays/countries/germany.py
Germany.start_year changed 1990 → 1991; removed year checks around multiple public-holiday additions (now unconditional); subdivision holiday logic unguarded; holiday label standardized to "Frauentag"/"Women's Day".
Localization Updates
holidays/locale/de/LC_MESSAGES/DE.po, holidays/locale/en_US/LC_MESSAGES/DE.po, holidays/locale/th/LC_MESSAGES/DE.po, holidays/locale/uk/LC_MESSAGES/DE.po
PO headers bumped (0.78→0.87, revision dates, last-translator); replaced "Internationaler Frauentag"/"International Women's Day" entries with "Frauentag"/"Women's Day" and updated msgid/msgstr pairs.
Snapshot Data Cleanup
snapshots/countries/DE_*.json (e.g., DE_AUGSBURG.json, DE_BE.json, DE_BW.json, DE_BY.json, DE_COMMON.json, DE_MV.json, DE_NW.json, DE_RP.json, DE_SN.json, DE_ST.json, etc.)
Removed multiple 1990 holiday entries (German Unity Day, All Saints'/Reformation Day variants, Repentance & Prayer Day, Christmas Day, Second Day of Christmas) across state snapshots; many snapshots also updated holiday label for Women's Day.
Tests
tests/countries/test_germany.py
Updated test expectations to use broader ranges (full_range), renamed test_international_womens_daytest_womens_day, and aligned localized name expectations with "Frauentag"/"Women's Day".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • Review focus:
    • holidays/countries/germany.py — confirm removal of year guards and that unconditional additions are intended across historical ranges.
    • Snapshot removals — verify consistency for all 1990 deletions across state files.
    • Locale .po changes — ensure msgid/msgstr consistency and correct metadata bumps.

Possibly related PRs

Suggested reviewers

  • PPsyrius
  • arkid15r

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update Germany holidays' directly and accurately summarizes the main change: updating German holiday definitions, start year, and holiday names.
Description check ✅ Passed The description is well-related to the changeset, clearly stating the two main objectives: changing start_year to 1991 and updating the Mar 8 holiday name per current laws.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 871bfbf and 196423e.

📒 Files selected for processing (1)
  • holidays/countries/germany.py (8 hunks)
🧰 Additional context used
🧠 Learnings (30)
📓 Common learnings
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_belgium.py:28-30
Timestamp: 2025-09-20T12:21:50.877Z
Learning: Belgium holidays implementation currently lacks a start_year attribute. In tests/countries/test_belgium.py, do not suggest adding test_no_holidays methods that rely on start_year until the start_year attribute is introduced to Belgium's holiday implementation.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_french_polynesia.py:19-22
Timestamp: 2025-11-08T05:09:56.159Z
Learning: In the vacanza/holidays project's test framework (PR #2881 onwards), the base class CommonCountryTests provides a default test_no_holidays implementation that automatically tests years=start_year - 1 for standard PUBLIC category cases. Individual country test files should only override test_no_holidays when the country supports additional non-PUBLIC categories (GOVERNMENT, WORKDAY, OPTIONAL, etc.) with different start years requiring separate validation.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:300-319
Timestamp: 2025-06-18T10:21:01.376Z
Learning: In the France holidays implementation, legislative years for holiday changes should be hard-coded rather than extracted into constants, as this maintains consistency with the existing codebase pattern and provides historical accuracy for specific legislative acts.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2777
File: holidays/countries/gambia.py:120-122
Timestamp: 2025-08-03T13:48:11.910Z
Learning: When reviewing holiday implementations in the holidays library, defer to the maintainers' choice of start years for specific holiday policies, as they likely have access to more reliable primary sources and official documentation than what can be found through web searches.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2874
File: tests/countries/test_taiwan.py:379-381
Timestamp: 2025-08-31T09:54:22.093Z
Learning: In Taiwan's holiday system, some holidays like Women's Day can appear in multiple categories simultaneously. Women's Day appears in the WORKDAY category for regular March 8th dates but also has special observed dates in the OPTIONAL category (1998-2000) when it was moved before Tomb-Sweeping Day. The test cases correctly reflect this dual-category behavior.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_south_africa.py:22-22
Timestamp: 2025-09-14T04:41:10.139Z
Learning: South Africa's observed holiday system only started in 1995, so in tests/countries/test_south_africa.py, using years_non_observed=range(1995, 2050) is intentional to limit testing to years where observed holidays actually exist, improving both correctness and performance.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2654
File: holidays/locale/de/LC_MESSAGES/CV.po:37-40
Timestamp: 2025-07-04T08:54:03.203Z
Learning: In German localization for Cape Verde holidays, "Dia da Nacionalidade e dos Heróis Nacionais" is translated as "Tag der Nationalhelden" (not "Tag der Nationalität und der Nationalhelden") based on authoritative German language sources about Cape Verde holidays, specifically from feelcaboverde.com.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2654
File: holidays/locale/de/LC_MESSAGES/CV.po:37-40
Timestamp: 2025-07-04T08:54:03.203Z
Learning: In German localization for Cape Verde holidays, "Dia da Nacionalidade e dos Heróis Nacionais" is translated as "Tag der Nationalhelden" (not "Tag der Nationalität und der Nationalhelden") based on authoritative German language sources about Cape Verde holidays, specifically from feelcaboverde.com.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.180Z
Learning: In the France holidays implementation, the _populate_subdiv_57_public_holidays() (Moselle) and _populate_subdiv_6ae_public_holidays() (Alsace) methods are functionally identical, both adding Good Friday (≥1893) and Saint Stephen's Day (≥1892) with the same legal references from August 16th, 1892. Therefore, for the deprecated "Alsace-Moselle" subdivision, calling either method produces the same result.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.447Z
Learning: In the France holidays implementation, deprecated subdivision names like "Alsace-Moselle" and "Saint-Barthélémy" are handled through explicit conditionals in _populate_public_holidays() that map them to their corresponding new subdivision-specific holiday population methods, providing backward compatibility while users transition to the new ISO codes.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2942
File: holidays/countries/south_africa.py:91-98
Timestamp: 2025-09-18T07:01:12.236Z
Learning: In the holidays library South Africa implementation, inline ternary operators for holiday name selection (like "Republic Day" if self._year >= 1961 else "Union Day") are intentionally kept inline rather than extracted to separate variables, as this structure is designed in preparation for future localization (l10n) support where the contextual relationship between conditions and translatable strings needs to be preserved.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_colombia.py:45-61
Timestamp: 2025-09-20T15:37:21.301Z
Learning: In Colombia's holiday system, movable observed holidays were only introduced from 1984 onwards. Before this date, holidays that later became movable (like Saint Joseph's Day) existed as regular holidays from their introduction year, but had no observed variant system. The years_non_observed parameter in Colombia tests reflects this 1984 start date for the observed holiday system.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_algeria.py:28-30
Timestamp: 2025-09-18T03:19:23.722Z
Learning: In the vacanza/holidays project, tests now use self.start_year and self.end_year from the TestCase class instead of country-specific aliases (like DZ.start_year) for start_year and end_year references. This approach provides the test framework with better control over test year ranges rather than being tied to specific country start years.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2653
File: holidays/locale/th/LC_MESSAGES/TW.po:17-21
Timestamp: 2025-06-21T18:06:50.027Z
Learning: KJhellico's username includes a tilde character (~) as part of their nickname (appears as "~Jhellico" in Last-Translator headers), which is intentional formatting and not an error.
📚 Learning: 2025-09-20T12:21:50.877Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_belgium.py:28-30
Timestamp: 2025-09-20T12:21:50.877Z
Learning: Belgium holidays implementation currently lacks a start_year attribute. In tests/countries/test_belgium.py, do not suggest adding test_no_holidays methods that rely on start_year until the start_year attribute is introduced to Belgium's holiday implementation.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-14T11:05:21.250Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2609
File: holidays/countries/nauru.py:48-50
Timestamp: 2025-06-14T11:05:21.250Z
Learning: In the holidays library, newer implementations use `start_year` to indicate the earliest year with complete holiday data coverage, not necessarily the first year a holiday existed. If a holiday system starts partway through a year (like Nauru's Public Holidays Act starting Jan 31, 1968), the start_year should be set to the following year (1969) to ensure users get full annual holiday coverage.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-14T11:04:31.180Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2609
File: holidays/countries/nauru.py:57-60
Timestamp: 2025-06-14T11:04:31.180Z
Learning: In the holidays library, the base `HolidayBase._populate()` method already includes a guard clause that prevents holiday population methods like `_populate_public_holidays()` from being called when the year is before `start_year` or after `end_year`. Therefore, individual country implementations do not need to add their own guard clauses for years before independence or other start dates.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-09-18T03:19:23.722Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_algeria.py:28-30
Timestamp: 2025-09-18T03:19:23.722Z
Learning: In the vacanza/holidays project, tests now use self.start_year and self.end_year from the TestCase class instead of country-specific aliases (like DZ.start_year) for start_year and end_year references. This approach provides the test framework with better control over test year ranges rather than being tied to specific country start years.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-09-10T16:17:30.428Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_bosnia_and_herzegovina.py:21-24
Timestamp: 2025-09-10T16:17:30.428Z
Learning: Bosnia and Herzegovina holidays implementation currently lacks a start_year attribute. In tests/countries/test_bosnia_and_herzegovina.py, using cls.full_range = range(2000, 2050) is intentional to bound assertions and setup. Do not suggest replacing it with harness default full_range until start_year is introduced.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-09-14T04:41:10.139Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_south_africa.py:22-22
Timestamp: 2025-09-14T04:41:10.139Z
Learning: South Africa's observed holiday system only started in 1995, so in tests/countries/test_south_africa.py, using years_non_observed=range(1995, 2050) is intentional to limit testing to years where observed holidays actually exist, improving both correctness and performance.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-09-17T09:07:56.459Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_paraguay.py:134-139
Timestamp: 2025-09-17T09:07:56.459Z
Learning: In the vacanza/holidays project, for holidays that start from a specific year (not the country's start_year), the standard pattern is to use `range(specific_year, self.end_year)` rather than `self.full_range` with year conditions. This maintains consistency across the codebase and clearly separates the holiday period from the pre-holiday period using `assertNoHolidayName(name, range(self.start_year, specific_year))`.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-18T10:21:01.376Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:300-319
Timestamp: 2025-06-18T10:21:01.376Z
Learning: In the France holidays implementation, legislative years for holiday changes should be hard-coded rather than extracted into constants, as this maintains consistency with the existing codebase pattern and provides historical accuracy for specific legislative acts.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-11-08T05:09:56.159Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: tests/countries/test_french_polynesia.py:19-22
Timestamp: 2025-11-08T05:09:56.159Z
Learning: In the vacanza/holidays project's test framework (PR #2881 onwards), the base class CommonCountryTests provides a default test_no_holidays implementation that automatically tests years=start_year - 1 for standard PUBLIC category cases. Individual country test files should only override test_no_holidays when the country supports additional non-PUBLIC categories (GOVERNMENT, WORKDAY, OPTIONAL, etc.) with different start years requiring separate validation.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-08-08T21:52:45.289Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2763
File: holidays/groups/mandaean.py:58-69
Timestamp: 2025-08-08T21:52:45.289Z
Learning: HolidayBase in the holidays library has a default end_year = 2100 (defined as DEFAULT_END_YEAR in holidays/constants.py), which is automatically inherited by all country classes unless explicitly overridden.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-18T10:26:50.180Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.180Z
Learning: In the France holidays implementation, the _populate_subdiv_57_public_holidays() (Moselle) and _populate_subdiv_6ae_public_holidays() (Alsace) methods are functionally identical, both adding Good Friday (≥1893) and Saint Stephen's Day (≥1892) with the same legal references from August 16th, 1892. Therefore, for the deprecated "Alsace-Moselle" subdivision, calling either method produces the same result.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-03-30T20:18:46.006Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2386
File: holidays/countries/nepal.py:24-26
Timestamp: 2025-03-30T20:18:46.006Z
Learning: In the holidays library, country classes do not directly implement `_populate()`. Instead, they implement specialized methods like `_populate_public_holidays()`, and the base class `HolidayBase` handles the orchestration by calling these specialized methods.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-04-13T20:42:13.152Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2386
File: holidays/countries/nepal.py:52-60
Timestamp: 2025-04-13T20:42:13.152Z
Learning: In the holidays library, country classes follow a consistent initialization pattern: first explicitly initializing each parent holiday group class with their specific parameters, then calling `super().__init__(*args, **kwargs)` at the end to properly initialize the base `HolidayBase` class.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-13T12:18:03.539Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2614
File: holidays/countries/guyana.py:78-90
Timestamp: 2025-06-13T12:18:03.539Z
Learning: The holidays codebase now uses the constructor signature pattern `__init__(self, *args, islamic_show_estimated: bool = True, **kwargs)` across country classes.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-18T10:07:58.780Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/french_southern_territories.py:41-44
Timestamp: 2025-06-18T10:07:58.780Z
Learning: Territorial holiday classes that inherit from parent countries (like HolidaysAX from Finland, HolidaysSJ from Norway, HolidaysTF from France) follow a standard pattern of silently overriding self.subdiv in their _populate_public_holidays() method without validation, as this ensures they always use the correct subdivision code for their territory regardless of user input.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-03-29T17:55:09.799Z
Learnt from: ankushhKapoor
Repo: vacanza/holidays PR: 2386
File: holidays/countries/nepal.py:29-34
Timestamp: 2025-03-29T17:55:09.799Z
Learning: In the holidays library, classes with multiple inheritance from various holiday groups (like ChristianHolidays, HinduCalendarHolidays, etc.) should initialize each parent class separately rather than using `super().__init__(*args, **kwargs)` because the parent classes have different parameter requirements. HolidayBase should receive the `*args, **kwargs` while other holiday group classes typically don't accept parameters like `observed`.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-15T15:24:53.055Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2606
File: holidays/countries/faroe_islands.py:62-67
Timestamp: 2025-06-15T15:24:53.055Z
Learning: The `HolidayBase` class uses `__getattr__` to dynamically implement `_add_holiday_*` methods through pattern matching, including patterns like `_add_holiday_<n>_days_past_easter`, `_add_holiday_<month>_<day>`, and various weekday-relative patterns. Methods like `_add_holiday_26_days_past_easter` are not explicitly defined but are dynamically generated when called.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-08-21T04:56:03.780Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2843
File: holidays/countries/burundi.py:63-101
Timestamp: 2025-08-21T04:56:03.780Z
Learning: In the holidays library, countries with localization support consistently use tr() wrappers around holiday names when calling _add_* methods (e.g., self._add_new_years_day(tr("Holiday Name"))). This is the established pattern across United States, Thailand, and other l10n-enabled countries, contrary to any suggestion that translation is handled internally by _add_* methods.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-10-28T17:26:45.090Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 3026
File: holidays/countries/spain.py:189-189
Timestamp: 2025-10-28T17:26:45.090Z
Learning: In the vacanza/holidays codebase, `_populate` methods (such as `_populate_public_holidays`, `_populate_subdiv_holidays`, and subdivision-specific methods like `_populate_subdiv_XX_public_holidays`) intentionally do not include return type annotations like `-> None`. This is a consistent pattern across country implementations (e.g., Germany, United States, Spain) and should not be changed even when static analysis tools like Ruff suggest adding them.
<!-- </add_learning>

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-18T10:58:28.058Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:184-206
Timestamp: 2025-06-18T10:58:28.058Z
Learning: In the holidays library France implementation, creating shared private methods between subdivision-specific holiday population methods (like _populate_subdiv_57_public_holidays and _populate_subdiv_6ae_public_holidays) is not supported by the current framework architecture, so duplicate code between functionally identical subdivision methods should be left as-is.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-18T10:18:59.447Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.447Z
Learning: In the France holidays implementation, deprecated subdivision names like "Alsace-Moselle" and "Saint-Barthélémy" are handled through explicit conditionals in _populate_public_holidays() that map them to their corresponding new subdivision-specific holiday population methods, providing backward compatibility while users transition to the new ISO codes.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-07-10T03:36:16.461Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2706
File: holidays/countries/cayman_islands.py:80-97
Timestamp: 2025-07-10T03:36:16.461Z
Learning: In the holidays library, date dictionaries that map years to specific dates (like queens_birthday_dates, special holiday dates, etc.) are typically defined within the _populate_public_holidays method rather than as module-level constants. This is the established library-wide pattern and should be maintained for consistency.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-16T11:46:35.303Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2638
File: holidays/countries/svalbard_and_jan_mayen.py:26-32
Timestamp: 2025-06-16T11:46:35.303Z
Learning: When creating country holiday aliases that inherit from parent countries (like Svalbard and Jan Mayen from Norway, or Åland from Finland), it's standard practice to hardcode a specific subdivision code in the _populate methods since the subdivision codes for the parent country yield identical results. The Åland Islands implementation serves as the reference pattern for this approach.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-07-10T03:36:16.461Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2706
File: holidays/countries/cayman_islands.py:80-97
Timestamp: 2025-07-10T03:36:16.461Z
Learning: In the holidays library, date dictionaries that map years to specific dates (like queens_birthday_dates, spring_bank_dates, thanksgiving_day_dates, etc.) are typically defined within the _populate_public_holidays method rather than as module-level constants. This is the established library-wide pattern seen across multiple country implementations including United Kingdom, United States, Sri Lanka, and others.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-08-24T06:53:35.897Z
Learnt from: Wasif-Shahzad
Repo: vacanza/holidays PR: 2852
File: holidays/countries/tajikistan.py:55-56
Timestamp: 2025-08-24T06:53:35.897Z
Learning: In Tajikistan, March 8th is celebrated as Mother's Day (Рӯзи Модар) rather than International Women's Day, so the country-specific implementation should use _add_holiday_mar_8() rather than the shared _add_womens_day() helper from InternationalHolidays.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-08-21T04:56:03.780Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2843
File: holidays/countries/burundi.py:63-101
Timestamp: 2025-08-21T04:56:03.780Z
Learning: In the holidays library, countries with localization support DO use tr() wrappers around holiday names when calling _add_* methods. This is the correct pattern for l10n-enabled country implementations, contrary to previous learning about translation being handled internally by _add_* methods.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-09-18T07:01:12.236Z
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2942
File: holidays/countries/south_africa.py:91-98
Timestamp: 2025-09-18T07:01:12.236Z
Learning: In the holidays library South Africa implementation, inline ternary operators for holiday name selection (like "Republic Day" if self._year >= 1961 else "Union Day") are intentionally kept inline rather than extracted to separate variables, as this structure is designed in preparation for future localization (l10n) support where the contextual relationship between conditions and translatable strings needs to be preserved.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-04-03T16:58:27.175Z
Learnt from: Wasif-Shahzad
Repo: vacanza/holidays PR: 2409
File: holidays/countries/qatar.py:27-46
Timestamp: 2025-04-03T16:58:27.175Z
Learning: In the holidays library, method names like `_add_holiday_2nd_tue_of_feb()` and `_add_holiday_1st_sun_of_mar()` use calendar constants like FEB, TUE, MAR, and SUN internally through parent class implementations even when these constants don't appear directly in the file.

Applied to files:

  • holidays/countries/germany.py
📚 Learning: 2025-06-14T20:12:37.212Z
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2614
File: holidays/countries/guyana.py:146-179
Timestamp: 2025-06-14T20:12:37.212Z
Learning: The `_CustomHinduHolidays` mechanism works through `_CustomCalendarType` metaclass which renames public attributes (like `DIWALI_INDIA_DATES`) with a postfix, allowing `_HinduLunisolar::_get_holiday` to find and use custom holiday dates. When `_add_diwali_india()` is called, it uses the custom dates if available rather than calculated dates.

Applied to files:

  • holidays/countries/germany.py
🧬 Code graph analysis (1)
holidays/countries/germany.py (2)
holidays/groups/international.py (3)
  • _add_new_years_day (142-150)
  • _add_labor_day (115-124)
  • _add_womens_day (203-213)
holidays/groups/christian.py (10)
  • _add_good_friday (344-353)
  • _add_easter_monday (275-284)
  • _add_ascension_thursday (133-141)
  • _add_whit_monday (498-507)
  • _add_easter_sunday (286-295)
  • _add_whit_sunday (509-519)
  • _add_epiphany_day (306-328)
  • _add_corpus_christi_day (263-273)
  • _add_all_saints_day (111-119)
  • _add_assumption_of_mary_day (162-180)
🪛 Ruff (0.14.7)
holidays/countries/germany.py

151-151: Missing return type annotation for private function _populate_subdiv_be_public_holidays

Add return type annotation: None

(ANN202)


156-156: Missing return type annotation for private function _populate_subdiv_bw_public_holidays

Add return type annotation: None

(ANN202)


166-166: Missing return type annotation for private function _populate_subdiv_by_public_holidays

Add return type annotation: None

(ANN202)


176-176: Missing return type annotation for private function _populate_subdiv_by_catholic_holidays

Add return type annotation: None

(ANN202)


180-180: Missing return type annotation for private function _populate_subdiv_hb_public_holidays

Add return type annotation: None

(ANN202)


185-185: Missing return type annotation for private function _populate_subdiv_he_public_holidays

Add return type annotation: None

(ANN202)


214-214: Missing return type annotation for private function _populate_subdiv_rp_public_holidays

Add return type annotation: None

(ANN202)


248-248: Missing return type annotation for private function _populate_subdiv_st_public_holidays

Add return type annotation: None

(ANN202)


267-267: Missing return type annotation for private function _populate_subdiv_augsburg_public_holidays

Add return type annotation: None

(ANN202)

⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test Python 3.12 on windows-latest
  • GitHub Check: Test Python 3.11 on windows-latest
  • GitHub Check: Test Python 3.14 on windows-latest
  • GitHub Check: Test Python 3.13 on windows-latest
  • GitHub Check: Test Python 3.10 on windows-latest
🔇 Additional comments (9)
holidays/countries/germany.py (9)

55-56: Solid rationale for start_year adjustment.

Setting start_year = 1991 makes sense — German reunification completed on Oct 3, 1990, so 1991 is indeed the first full calendar year of unified Germany. The comment clearly documents the reasoning.


106-140: Clean simplification of holiday population logic.

Removing per-holiday year guards is appropriate since the base class already prevents population before start_year. The _year <= 1994 guard for Repentance and Prayer Day correctly reflects its abolition as a national holiday.


141-149: LGTM.

Brandenburg holidays now rely on start_year for year boundary, which is consistent with the rest of the file.


156-164: LGTM.

Baden-Württemberg holidays simplified consistently.


166-178: LGTM.

Bavaria public and catholic holidays follow the simplified pattern.


194-200: LGTM.

Mecklenburg-Vorpommern's Women's Day uses consistent naming ("Frauentag") and correctly retains the _year >= 2023 guard for when this subdivision adopted the holiday.


236-271: LGTM.

Subdivision-specific year guards are correctly retained where they represent local adoption dates (Saxony's Repentance Day from 1995, Thuringia's World Children's Day from 2019). The Augsburg Peace Festival simplification is consistent.


282-319: Static holidays section unchanged and well-documented.

The GermanyStaticHolidays class with special holidays for 2017, 2020, 2025, and 2028 remains intact with clear archive.org references.


151-154: Incorrect holiday name change—Berlin's current official name is "Internationaler Frauentag", not "Frauentag".

The year >= 2019 is correct, as Berlin first observed this holiday on 8 March 2019. However, the name change from "Internationaler Frauentag" to "Frauentag" contradicts the stated PR objective of matching current legal naming. Berlin's official name remains "Internationaler Frauentag" as confirmed by 2024-2025 sources.

⛔ Skipped due to learnings
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: holidays/countries/south_africa.py:163-170
Timestamp: 2025-09-14T06:39:08.485Z
Learning: In South Africa's holidays implementation (holidays/countries/south_africa.py), the 2021 election uses the literal "Municipal elections" instead of the local_elections constant ("Local Government Elections") - this inconsistency is intentional and should not be flagged as an issue.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2750
File: tests/countries/test_germany.py:46-46
Timestamp: 2025-07-24T15:21:31.632Z
Learning: In the holidays project test files, the standard method name for testing the absence of holidays is `test_no_holidays`, not more descriptive names like `test_no_holidays_before_1990`. This is a consistent naming convention across country test files like France and Germany.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2750
File: tests/countries/test_germany.py:46-46
Timestamp: 2025-07-24T15:21:31.632Z
Learning: In the holidays project test files, the standard method name for testing the absence of holidays is `test_no_holidays`, not more descriptive names like `test_no_holidays_before_1990`. This is a consistent naming convention across country test files like France and Germany.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2777
File: holidays/countries/gambia.py:120-122
Timestamp: 2025-08-03T13:48:11.910Z
Learning: When reviewing holiday implementations in the holidays library, defer to the maintainers' choice of start years for specific holiday policies, as they likely have access to more reliable primary sources and official documentation than what can be found through web searches.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 3088
File: tests/countries/test_dr_congo.py:162-168
Timestamp: 2025-11-27T13:48:37.538Z
Learning: In DR Congo's holiday implementation (tests/countries/test_dr_congo.py), the test_congolese_genocide_memorial_day method cannot use assertNoNonObservedHoliday because when Aug 2 is observed on Aug 1 (in year 2026), that date already has another holiday: "Fête des parents" (Aug 1). The observed holiday overlaps with an existing non-observed holiday, making the standard non-observed holiday check inappropriate.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2881
File: holidays/countries/south_africa.py:69-75
Timestamp: 2025-09-14T07:26:25.431Z
Learning: When reviewing historical holiday implementations in the vacanza/holidays repository, trust the maintainers' research and implementation decisions for specific historical edge cases, especially when they can provide sources like Wikipedia or other historical documentation that supports unusual or complex date calculation rules during specific time periods.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2960
File: holidays/locale/ca/LC_MESSAGES/ES.po:148-151
Timestamp: 2025-09-26T13:58:49.363Z
Learning: In the holidays project, when translating holiday names in .po files, the msgstr should be a faithful translation of the original msgid (in the country's default language), not influenced by English commentary or common en_US names. For example, "Día de la Pascua Granada" (Spanish) correctly translates to "Dia de la Pasqua Granada" (Catalan), even though the English comment refers to it as "Whit Monday".
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2537
File: holidays/countries/finland.py:249-253
Timestamp: 2025-05-10T04:02:13.815Z
Learning: Holiday name comments directly above tr() function calls in the holidays package should only contain the holiday name itself (e.g., "# Independence Day.") without any additional context, dates, or historical information.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2833
File: holidays/countries/uganda.py:50-56
Timestamp: 2025-08-25T09:57:22.291Z
Learning: In the holidays package, when adding comments for year-restricted holidays in Uganda and similar country modules, include specific legal or historical context such as the actual laws, parliamentary acts, or government decisions that established the holidays, rather than just generic "since YEAR" information. For example, reference the specific Parliament act, decree, or historical event that created the holiday.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2831
File: holidays/countries/south_sudan.py:84-88
Timestamp: 2025-08-19T21:22:13.125Z
Learning: In the holidays library, message comments directly above holiday addition methods must match the holiday name exactly without any additions, modifications, or explanatory text. For example, if the holiday name is "Eid al-Fitr Holiday", the comment should be "# Eid al-Fitr Holiday." with no extra context.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/french_southern_territories.py:41-44
Timestamp: 2025-06-18T10:07:58.780Z
Learning: Territorial holiday classes that inherit from parent countries (like HolidaysAX from Finland, HolidaysSJ from Norway, HolidaysTF from France) follow a standard pattern of silently overriding self.subdiv in their _populate_public_holidays() method without validation, as this ensures they always use the correct subdivision code for their territory regardless of user input.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 2386
File: holidays/countries/nepal.py:24-26
Timestamp: 2025-03-30T20:18:46.006Z
Learning: In the holidays library, country classes do not directly implement `_populate()`. Instead, they implement specialized methods like `_populate_public_holidays()`, and the base class `HolidayBase` handles the orchestration by calling these specialized methods.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 3026
File: holidays/countries/spain.py:189-189
Timestamp: 2025-10-28T17:26:45.090Z
Learning: In the vacanza/holidays codebase, `_populate` methods (such as `_populate_public_holidays`, `_populate_subdiv_holidays`, and subdivision-specific methods like `_populate_subdiv_XX_public_holidays`) intentionally do not include return type annotations like `-> None`. This is a consistent pattern across country implementations (e.g., Germany, United States, Spain) and should not be changed even when static analysis tools like Ruff suggest adding them.
<!-- </add_learning>
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.180Z
Learning: In the France holidays implementation, the _populate_subdiv_57_public_holidays() (Moselle) and _populate_subdiv_6ae_public_holidays() (Alsace) methods are functionally identical, both adding Good Friday (≥1893) and Saint Stephen's Day (≥1892) with the same legal references from August 16th, 1892. Therefore, for the deprecated "Alsace-Moselle" subdivision, calling either method produces the same result.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:184-206
Timestamp: 2025-06-18T10:58:28.058Z
Learning: In the holidays library France implementation, creating shared private methods between subdivision-specific holiday population methods (like _populate_subdiv_57_public_holidays and _populate_subdiv_6ae_public_holidays) is not supported by the current framework architecture, so duplicate code between functionally identical subdivision methods should be left as-is.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2609
File: holidays/countries/nauru.py:57-60
Timestamp: 2025-06-14T11:04:31.180Z
Learning: In the holidays library, the base `HolidayBase._populate()` method already includes a guard clause that prevents holiday population methods like `_populate_public_holidays()` from being called when the year is before `start_year` or after `end_year`. Therefore, individual country implementations do not need to add their own guard clauses for years before independence or other start dates.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.447Z
Learning: In the France holidays implementation, deprecated subdivision names like "Alsace-Moselle" and "Saint-Barthélémy" are handled through explicit conditionals in _populate_public_holidays() that map them to their corresponding new subdivision-specific holiday population methods, providing backward compatibility while users transition to the new ISO codes.
Learnt from: Wasif-Shahzad
Repo: vacanza/holidays PR: 2852
File: holidays/countries/tajikistan.py:55-56
Timestamp: 2025-08-24T06:53:35.897Z
Learning: In Tajikistan, March 8th is celebrated as Mother's Day (Рӯзи Модар) rather than International Women's Day, so the country-specific implementation should use _add_holiday_mar_8() rather than the shared _add_womens_day() helper from InternationalHolidays.
Learnt from: PPsyrius
Repo: vacanza/holidays PR: 2706
File: holidays/countries/cayman_islands.py:80-97
Timestamp: 2025-07-10T03:36:16.461Z
Learning: In the holidays library, date dictionaries that map years to specific dates (like queens_birthday_dates, special holiday dates, etc.) are typically defined within the _populate_public_holidays method rather than as module-level constants. This is the established library-wide pattern and should be maintained for consistency.
Learnt from: KJhellico
Repo: vacanza/holidays PR: 3008
File: holidays/financial/_sifma.py:146-150
Timestamp: 2025-10-27T21:23:12.690Z
Learning: In the holidays library, `_christmas_day` is a property defined in the `ChristianHolidays` mixin class and is always available to any class that inherits from `ChristianHolidays`, regardless of whether `_populate_public_holidays` is called or which categories are requested. It does not depend on populating public holidays.

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.

@codecov
Copy link
Copy Markdown

codecov bot commented Dec 2, 2025

Codecov Report

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

Additional details and impacted files
@@            Coverage Diff            @@
##               dev     #3102   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          306       306           
  Lines        18096     18083   -13     
  Branches      2305      2292   -13     
=========================================
- Hits         18096     18083   -13     

☔ 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.

Copy link
Copy Markdown
Collaborator

@arkid15r arkid15r 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 enabled auto-merge December 2, 2025 18:36
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Dec 2, 2025

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 added this pull request to the merge queue Dec 3, 2025
Merged via the queue into vacanza:dev with commit 1e24265 Dec 3, 2025
33 checks passed
@KJhellico KJhellico deleted the upd-germany branch December 3, 2025 16:05
@KJhellico KJhellico mentioned this pull request Dec 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants