Skip to content

Update France holidays: refactors, add th l10n#2642

Merged
arkid15r merged 21 commits intovacanza:devfrom
PPsyrius:FR_refactor
Jun 19, 2025
Merged

Update France holidays: refactors, add th l10n#2642
arkid15r merged 21 commits intovacanza:devfrom
PPsyrius:FR_refactor

Conversation

@PPsyrius
Copy link
Collaborator

@PPsyrius PPsyrius commented Jun 18, 2025

Proposed change

  • Move French start_year to 1803, in line with modern library-wide practice.
  • Add and archive all new references for French Public Holidays.
  • Remove unneeded deprecation (already supported by subdivisions_aliases).
  • Deprecated GES subdivision (the 2 special holidays are only in effect for Alsace and Moselle, not the whole region), change to proper ISO 3166-2:FR code of 57 and 6AE accordingly.
  • Add all missing ISO 3166-2:FR subdivisions that has their own ISO 3166-1 code.
  • Refactor test cases to modern library-wide standards.
  • Add th l10n support.
  • Add country-level stub for all applicable ISO 3166-2:FR subdivisions - 11 new countries in total (a revival of Add ISO 3166-1 for overseas departments and regions of France #1063).

Resolves #2411 .
Resolves #2429 .
Resolves #2430 .

Warning

This deprecates the existing GES subdivision for France's "Alsace-Moselle" holidays, please switch to either 57 (Moselle) or 6AE (Alsace) instead.

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
Contributor

coderabbitai bot commented Jun 18, 2025

Summary by CodeRabbit

  • New Features

    • Added official holiday support for French overseas territories: Guadeloupe, Martinique, French Guiana, Réunion, Mayotte, New Caledonia, French Polynesia, Saint Barthélemy, Saint Martin, Saint Pierre and Miquelon, Wallis and Futuna, and French Southern Territories.
    • Introduced Thai language translations for French and overseas territory holidays.
    • Expanded and clarified France's country code and subdivision handling, including explicit listings for overseas regions.
  • Bug Fixes

    • Corrected and updated holiday names, observance years, and legal references for France and its territories.
    • Improved accuracy and consistency of holiday datasets, including regional and historical changes.
  • Documentation

    • Updated documentation to reflect new country codes, subdivisions, and supported languages.
  • Tests

    • Added comprehensive tests for all new territories, ensuring correct holiday calculation and localization in multiple languages.
  • Localization

    • Added new translation files for English, French, Thai, and Ukrainian for all supported regions.

Summary by CodeRabbit

  • New Features

    • Added official holiday support for French overseas territories: Guadeloupe, Martinique, French Guiana, Mayotte, New Caledonia, Réunion, Saint Barthélemy, Saint Martin, Saint Pierre and Miquelon, Wallis and Futuna, and French Southern Territories, each with their own country codes and aliases.
    • Introduced detailed, historically accurate holiday calendars for France and its subdivisions, including overseas territories, with improved regional and legal distinctions.
    • Expanded localization support for these regions, including new translation files in French, English (US), Thai, and Ukrainian.
    • Added Thai language support for France and its subdivisions.
  • Bug Fixes

    • Corrected and clarified holiday names and observance dates, including updates to regional holidays and removal of outdated or incorrect entries.
  • Documentation

    • Updated README and translation files to reflect new country codes, subdivisions, and supported languages.
  • Tests

    • Comprehensive new and expanded tests for all added regions and languages, verifying holiday presence, names, and localization.
  • Chores

    • Added new static data files mapping holiday dates for all supported French territories.

Walkthrough

This change overhauls France holiday logic, subdivision codes, and historical holiday enactment years. It updates docstrings, aliases, and region-specific logic, expands and corrects test coverage, adjusts translation files, and adds or modifies JSON holiday snapshots for multiple French regions and territories, including new files for some subdivisions. The French Southern Territories class now explicitly sets subdivision during holiday population and supports Thai localization. New modules for Saint Pierre and Miquelon, Saint Martin, Saint Barthélemy, and Wallis and Futuna were added, each subclassing France with appropriate overrides.

Changes

Files/Groups Change Summary
README.md Expanded and clarified France subdivisions in the country table, listing more regions and codes including DOM, ROM, TOM, and new territories like Saint-Pierre-et-Miquelon and Terres australes françaises. Added Thai language support.
holidays/countries/france.py Major refactor: updated docstrings with historical/legal references, changed start_year to 1803, replaced subdivision codes with numeric/alphanumeric codes, updated aliases, added Thai support. Rewrote _populate_public_holidays with year-based conditions for holidays. Renamed and redefined subdivision-specific holiday methods with precise historical enactments and legal citations. Removed deprecated subdivisions and adjusted holiday logic accordingly.
holidays/countries/french_southern_territories.py Fixed ISO standard typo in docstring. Added _populate_public_holidays method setting subdivision to "TF" before calling parent method. Added Thai language support.
holidays/countries/saint_pierre_and_miquelon.py Added new module defining Saint Pierre and Miquelon holidays as subclass of France holidays with country code "PM", no subdivisions, start year 1815, and subdivision set to "PM" during holiday population. Added alias classes for convenience.
holidays/countries/wallis_and_futuna.py Added new module defining Wallis and Futuna holidays as subclass of France holidays with country code "WF", no subdivisions, start year 1962, and subdivision set to "WF" during holiday population. Added alias classes for convenience.
holidays/countries/saint_martin.py Added new module defining Saint Martin holidays as subclass of France holidays with country code "MF", no subdivisions, start year 2008, and subdivision set to "MF" during holiday population. Added alias classes for convenience.
holidays/countries/saint_barthelemy.py Added new module defining Saint Barthélemy holidays as subclass of France holidays with country code "BL", no subdivisions, start year 2008, and subdivision set to "BL" during holiday population. Added alias classes for convenience.
holidays/countries/guadeloupe.py Added new module defining Guadeloupe holidays as subclass of France holidays with country code "GP", no subdivisions, start year 1815, and subdivision set to "971" during holiday population. Added alias classes for convenience.
holidays/countries/martinique.py Added new module defining Martinique holidays as subclass of France holidays with country code "MQ", no subdivisions, start year 1803, and subdivision set to "972" during holiday population. Added alias classes for convenience.
holidays/countries/french_guiana.py Added new module defining French Guiana holidays as subclass of France holidays with country code "GF", no subdivisions, start year 1815, and subdivision set to "973" during holiday population. Added alias classes for convenience.
holidays/countries/reunion.py Added new module defining Réunion holidays as subclass of France holidays with country code "RE", no subdivisions, start year 1815, and subdivision set to "974" during holiday population. Added alias classes for convenience.
holidays/countries/mayotte.py Added new module defining Mayotte holidays as subclass of France holidays with country code "YT", no subdivisions, start year 1842, and subdivision set to "976" during holiday population. Added alias classes for convenience.
holidays/countries/new_caledonia.py Added new module defining New Caledonia holidays as subclass of France holidays with country code "NC", no subdivisions, start year 1854, and subdivision set to "NC" during holiday population. Added alias classes for convenience.
holidays/countries/french_polynesia.py Added new module defining French Polynesia holidays as subclass of France holidays with country code "PF", no subdivisions, start year 1881, and subdivision set to "PF" during holiday population. Added alias classes for convenience.
holidays/countries/__init__.py Added imports for Saint Martin, Saint Pierre and Miquelon, Saint Barthélemy, Wallis and Futuna, Guadeloupe, Martinique, French Guiana, Mayotte, New Caledonia, Réunion, and French Polynesia classes and aliases.
Localization files (holidays/locale/*/LC_MESSAGES/*.po) Updated metadata and refined holiday name translations (e.g., "Victor Schoelcher Day," "Abolition of Slavery," "Territory Day"). Added new holiday entries. Added new Thai translation files for France, French Southern Territories, Saint Martin, Saint Pierre and Miquelon, Saint Barthélemy, Wallis and Futuna, Guadeloupe, Martinique, French Guiana, Mayotte, New Caledonia, Réunion, and French Polynesia.
Snapshots (snapshots/countries/*.json) Added new JSON snapshot files for Alsace, Saint-Pierre-et-Miquelon, French Southern Territories, Saint Pierre and Miquelon common holidays, Saint Martin, Saint Barthélemy, Wallis and Futuna, Guadeloupe, Martinique, French Guiana, Mayotte, New Caledonia, Réunion, and French Polynesia, mapping dates to holidays (1950–2050). Removed or renamed "Abolition of Slavery" and "Victor Schoelcher Day" entries according to updated holiday logic for Guadeloupe, Martinique, Guyane, La Réunion, Mayotte, Saint-Barthélemy, and Saint Martin. Adjusted New Caledonia and French Polynesia holiday names and dates.
tests/countries/test_france.py Rewrote and expanded tests: added comprehensive, granular checks for holiday names, date ranges, and regional logic; improved setup and coverage over 1803–2049 and all subdivisions. Added localization tests including Thai.
tests/countries/test_french_southern_territories.py Replaced year 2022 test with 2024 test asserting holiday names and dates. Added localization tests for French, English, Ukrainian, and Thai.
tests/countries/test_saint_pierre_and_miquelon.py Added new test module for Saint Pierre and Miquelon holidays verifying holiday presence, absence, and localization in multiple languages.
tests/countries/test_saint_martin.py Added new test module for Saint Martin holidays verifying holiday presence, absence, and localization in multiple languages.
tests/countries/test_wallis_and_futuna.py Added new test module for Wallis and Futuna holidays verifying aliases, holiday presence from 1962 onward, and localization in multiple languages.
tests/countries/test_saint_barthelemy.py Added new test module for Saint Barthélemy holidays verifying aliases, holiday presence from 2008 onward, and localization in multiple languages.
tests/countries/test_guadeloupe.py Added new test module for Guadeloupe holidays verifying aliases, holiday presence from 1815 onward, and localization in multiple languages.
tests/countries/test_martinique.py Added new test module for Martinique holidays verifying aliases, holiday presence from 1803 onward, and localization in multiple languages.
tests/countries/test_french_guiana.py Added new test module for French Guiana holidays verifying aliases, holiday presence from 1815 onward, and localization in multiple languages.

Assessment against linked issues

Objective Addressed Explanation
Add Saint Barthélemy holidays (#2411)
Add Mayotte holidays (#2429)
Add Wallis and Futuna holidays (#2430)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes detected. All code changes align with the objectives provided.

Possibly related PRs

Suggested reviewers

  • KJhellico
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Post Copyable Unit Tests in 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link

codecov bot commented Jun 18, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (eed3824) to head (4daa313).
Report is 2 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##               dev     #2642    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files          235       246    +11     
  Lines        14869     15065   +196     
  Branches      2063      2069     +6     
==========================================
+ Hits         14869     15065   +196     

☔ 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
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: 11

🔭 Outside diff range comments (2)
holidays/locale/fr/LC_MESSAGES/FR.po (1)

85-131: New msgids still lack French translations.

All freshly added holidays (1er mai, Matāri'i, …) have empty msgstr.
Ship at least the source text as fallback to avoid blank names at runtime.
Example:

-msgid "Matāri'i"
-msgstr ""
+msgid "Matāri'i"
+msgstr "Matāri'i"
holidays/locale/en_US/LC_MESSAGES/FR.po (1)

57-60: Inconsistent accent handling.

French “Mi-Carême” became Mi-Careme (no accent) in the English msgstr.
Either keep the accent or use “Mid-Lent” to avoid mixed notation.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33202d2 and e308a68.

📒 Files selected for processing (21)
  • README.md (1 hunks)
  • holidays/countries/france.py (3 hunks)
  • holidays/countries/french_southern_territories.py (2 hunks)
  • holidays/locale/en_US/LC_MESSAGES/FR.po (3 hunks)
  • holidays/locale/fr/LC_MESSAGES/FR.po (3 hunks)
  • holidays/locale/uk/LC_MESSAGES/FR.po (3 hunks)
  • snapshots/countries/FR_6AE.json (1 hunks)
  • snapshots/countries/FR_971.json (70 hunks)
  • snapshots/countries/FR_972.json (70 hunks)
  • snapshots/countries/FR_973.json (1 hunks)
  • snapshots/countries/FR_974.json (0 hunks)
  • snapshots/countries/FR_976.json (0 hunks)
  • snapshots/countries/FR_BL.json (0 hunks)
  • snapshots/countries/FR_MF.json (39 hunks)
  • snapshots/countries/FR_NC.json (51 hunks)
  • snapshots/countries/FR_PF.json (26 hunks)
  • snapshots/countries/FR_PM.json (1 hunks)
  • snapshots/countries/FR_TF.json (1 hunks)
  • snapshots/countries/FR_WF.json (89 hunks)
  • tests/countries/test_france.py (5 hunks)
  • tests/countries/test_french_southern_territories.py (1 hunks)
💤 Files with no reviewable changes (3)
  • snapshots/countries/FR_974.json
  • snapshots/countries/FR_BL.json
  • snapshots/countries/FR_976.json
🧰 Additional context used
🧠 Learnings (1)
tests/countries/test_france.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.
🪛 Pylint (3.3.7)
tests/countries/test_france.py

[convention] 36-36: Missing function or method docstring

(C0116)


[convention] 39-39: Missing function or method docstring

(C0116)


[convention] 55-55: Missing function or method docstring

(C0116)


[convention] 71-71: Missing function or method docstring

(C0116)


[convention] 74-74: Missing function or method docstring

(C0116)


[convention] 84-84: Missing function or method docstring

(C0116)


[convention] 89-89: Missing function or method docstring

(C0116)


[convention] 104-104: Missing function or method docstring

(C0116)


[convention] 119-119: Missing function or method docstring

(C0116)


[convention] 134-134: Missing function or method docstring

(C0116)


[convention] 141-141: Missing function or method docstring

(C0116)


[convention] 146-146: Missing function or method docstring

(C0116)


[convention] 160-160: Missing function or method docstring

(C0116)


[convention] 163-163: Missing function or method docstring

(C0116)


[convention] 166-166: Missing function or method docstring

(C0116)


[convention] 171-171: Missing function or method docstring

(C0116)


[convention] 174-174: Missing function or method docstring

(C0116)


[convention] 199-199: Missing function or method docstring

(C0116)


[convention] 212-212: Missing function or method docstring

(C0116)


[convention] 232-232: Missing function or method docstring

(C0116)


[convention] 281-281: Missing function or method docstring

(C0116)


[convention] 300-300: Missing function or method docstring

(C0116)


[convention] 320-320: Missing function or method docstring

(C0116)


[convention] 333-333: Missing function or method docstring

(C0116)


[convention] 346-346: Missing function or method docstring

(C0116)


[convention] 359-359: Missing function or method docstring

(C0116)


[convention] 372-372: Missing function or method docstring

(C0116)


[convention] 385-385: Missing function or method docstring

(C0116)

holidays/countries/france.py

[convention] 25-25: Line too long (123/100)

(C0301)


[convention] 28-28: Line too long (126/100)

(C0301)


[convention] 29-29: Line too long (238/100)

(C0301)


[convention] 36-36: Line too long (148/100)

(C0301)


[convention] 39-39: Line too long (102/100)

(C0301)


[convention] 40-40: Line too long (148/100)

(C0301)


[convention] 41-41: Line too long (149/100)

(C0301)


[convention] 42-42: Line too long (151/100)

(C0301)


[convention] 43-43: Line too long (144/100)

(C0301)


[convention] 44-44: Line too long (103/100)

(C0301)


[convention] 45-45: Line too long (103/100)

(C0301)


[convention] 46-46: Line too long (124/100)

(C0301)


[convention] 47-47: Line too long (153/100)

(C0301)

⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Test Python 3.13 on windows-latest
🔇 Additional comments (25)
snapshots/countries/FR_973.json (1)

81-82: Removal of pre-1984 abolition entry looks accurate

Guyane’s observance of the Abolition of Slavery wasn’t legislated until 1983, so stripping it from the 1957 compound holiday record is historically correct. No further action needed.

snapshots/countries/FR_971.json (2)

425-432: Renaming to “Victor Schoelcher Day” aligns with PO updates

Starting in 1984 the holiday was renamed throughout the PO files; snapshot now reflects that. 👍


326-333: Ascension Day shift flagged – worth double-checking algorithm

Lines such as 1976-05-27 (Ascension) moved one day later compared to the old snapshot. This is probably the result of switching to library-wide Gregorian algorithm fixes, but please re-run holidays FR 1976 manually to confirm before merging.

snapshots/countries/FR_WF.json (2)

135-137: Approve new “Saints Peter and Paul Day” and “Territory Day” additions for 1962.
Entries for June 29 and the renamed July 29 holiday accurately capture Wallis and Futuna’s historical observances.


148-1349: Subsequent entries from 1963 through 2050 repeat the same pattern of adding June 29 (“Saints Peter and Paul Day”) and renaming July 29 (“Territory Day”). No further comments.

snapshots/countries/FR_PF.json (2)

970-970: Approve addition of “Matāri'i” holiday entries.
Introducing “Matāri'i” on November 20 from 2025 onward aligns correctly with updated definitions for French Polynesia.


984-1320: Subsequent “Matāri'i” entries for 2026–2050 follow the same pattern. No further comments.

snapshots/countries/FR_NC.json (1)

40-616: Verified Annexation Day period
All 09-24 entries from 1953 through 2003 have been correctly renamed to "Annexation Day", and entries revert to "Citizenship Day" starting in 2004. This aligns with the new _populate_subdiv_nc_public_holidays logic for Nouvelle-Calédonie.

snapshots/countries/FR_972.json (3)

28-28: Removed combined holiday for 1952
The 1952 entry has been decoupled—only "Ascension Day" remains on 05-22, with "Abolition of Slavery" correctly omitted before 1984.


394-1311: Renamed Victor Schoelcher holiday
All instances of "Feast of Victor Schoelcher" have been renamed to "Victor Schoelcher Day" starting in 1984, and "Abolition of Slavery" appears only from 1984 onward.


1041-1044: Inconsistent combined entry for 2031
The snapshot still shows a combined "Abolition of Slavery; Ascension Day" on 2031-05-22, but the summary indicates combined entries in 2031 should exclude "Abolition of Slavery". Please verify the intended behavior for 2031 and update the snapshot or code logic accordingly.

Likely an incorrect or invalid review comment.

README.md (1)

586-586: Subdivisions list updated for France
The new ISO 3166-2 codes (including PM, TF, WF) are correctly reflected in the table.

snapshots/countries/FR_MF.json (1)

658-661: New recurring holidays added across snapshot
The entries for "Abolition of Slavery" and "Victor Schoelcher Day" are consistently inserted for 2012 and beyond, matching the updated subdivision logic in france.py.

Also applies to: 671-673, 682-686, 697-699, 710-712, 722-725

holidays/locale/uk/LC_MESSAGES/FR.po (9)

17-21: Version and metadata bump
The PO headers have been updated to version 0.76 and new revision dates; ensure consistency with other locale files.


27-28: Generator updated
Poedit generator version bumped from 3.4 to 3.6—looks good.


85-88: Add "Victor Schoelcher Day" translation
The new msgid/msgstr pair correctly reflects the holiday rename.


89-92: Add "Abolition of Slavery" translation
The msgid and Ukrainian translation match the updated holiday name.


113-116: Add "Territory Day" translation
The new entry for "Fête du Territoire" is present and translated.


117-120: Add May Day translation
The "1er mai" entry is correctly localized.


121-124: Add Annexation Day translation
The "Fête de la prise de possession" translation aligns with the new holiday.


125-128: Add "Matāri'i" translation
The native wording is accurately carried over.


129-132: Add Saints Peter and Paul Day translation
The "Saints Pierre et Paul" msgid and Ukrainian msgstr are correctly paired.

snapshots/countries/FR_PM.json (1)

1-12: New snapshot for Saint-Pierre-et-Miquelon (FR_PM)
The JSON covers 1950–2050 with fixed and movable holidays aligned with the France module. This addition fills the missing subdivision snapshot.

holidays/locale/fr/LC_MESSAGES/FR.po (1)

15-28: Plural-Forms header removed – breaks msgfmt compilation.

msgfmt needs a Plural-Forms header to build the .mo.
Re-add the canonical French rule:

 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: Lingua 4.15.0\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
⛔ Skipped due to learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2537
File: holidays/locale/sv_FI/LC_MESSAGES/AX.po:17-27
Timestamp: 2025-05-10T04:34:02.406Z
Learning: The `Plural-Forms` header isn't used in .po file generation for the holidays project and doesn't need to be manually added to localization files.
snapshots/countries/FR_TF.json (1)

612-614: Comma-separated multiple names – ensure consumer code splits correctly.

Lines such as
"2008-05-01": "Ascension Day; Labor Day"
assume downstream renderers understand the semi-colon. Verify that the web/API layers don’t blindly use the entire string as a primary name.

Copy link
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: 6

🔭 Outside diff range comments (3)
snapshots/countries/FR_972.json (1)

944-952: Nitpick – duplicate name separator

There are still a few rows like
"Ascension Day; Victory Day" (line 417) where the semicolon separator is kept.

If the generator intentionally concatenates names when two holidays fall on the same date, consider switching to the library-wide " / " convention ("Ascension Day / Victory Day") for consistency with other countries.

snapshots/countries/FR_PF.json (1)

970-1320: Validate ‘Matāri’i’ holiday additions
The new “Matāri’i” entries on November 20 are added for each year from 2025 through 2050. Confirm that the series is complete (no missing years), correctly escaped (Mat\u0101ri'i), and placed between Armistice Day and Christmas Day in chronological order.

holidays/countries/french_southern_territories.py (1)

18-25: Minor wording tweak

"Since most islands doesn't have""Since most islands don't have"
Purely cosmetic, but reads better.

-        Since most islands doesn't have a permanent population,
+        Since most islands don't have a permanent population,
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33202d2 and e308a68.

📒 Files selected for processing (21)
  • README.md (1 hunks)
  • holidays/countries/france.py (3 hunks)
  • holidays/countries/french_southern_territories.py (2 hunks)
  • holidays/locale/en_US/LC_MESSAGES/FR.po (3 hunks)
  • holidays/locale/fr/LC_MESSAGES/FR.po (3 hunks)
  • holidays/locale/uk/LC_MESSAGES/FR.po (3 hunks)
  • snapshots/countries/FR_6AE.json (1 hunks)
  • snapshots/countries/FR_971.json (70 hunks)
  • snapshots/countries/FR_972.json (70 hunks)
  • snapshots/countries/FR_973.json (1 hunks)
  • snapshots/countries/FR_974.json (0 hunks)
  • snapshots/countries/FR_976.json (0 hunks)
  • snapshots/countries/FR_BL.json (0 hunks)
  • snapshots/countries/FR_MF.json (39 hunks)
  • snapshots/countries/FR_NC.json (51 hunks)
  • snapshots/countries/FR_PF.json (26 hunks)
  • snapshots/countries/FR_PM.json (1 hunks)
  • snapshots/countries/FR_TF.json (1 hunks)
  • snapshots/countries/FR_WF.json (89 hunks)
  • tests/countries/test_france.py (5 hunks)
  • tests/countries/test_french_southern_territories.py (1 hunks)
💤 Files with no reviewable changes (3)
  • snapshots/countries/FR_974.json
  • snapshots/countries/FR_976.json
  • snapshots/countries/FR_BL.json
🧰 Additional context used
🧠 Learnings (1)
tests/countries/test_france.py (2)
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.
🪛 Pylint (3.3.7)
holidays/countries/france.py

[convention] 25-25: Line too long (123/100)

(C0301)


[convention] 28-28: Line too long (126/100)

(C0301)


[convention] 29-29: Line too long (238/100)

(C0301)


[convention] 36-36: Line too long (148/100)

(C0301)


[convention] 39-39: Line too long (102/100)

(C0301)


[convention] 40-40: Line too long (148/100)

(C0301)


[convention] 41-41: Line too long (149/100)

(C0301)


[convention] 42-42: Line too long (151/100)

(C0301)


[convention] 43-43: Line too long (144/100)

(C0301)


[convention] 44-44: Line too long (103/100)

(C0301)


[convention] 45-45: Line too long (103/100)

(C0301)


[convention] 46-46: Line too long (124/100)

(C0301)


[convention] 47-47: Line too long (153/100)

(C0301)

tests/countries/test_france.py

[convention] 36-36: Missing function or method docstring

(C0116)


[convention] 39-39: Missing function or method docstring

(C0116)


[convention] 55-55: Missing function or method docstring

(C0116)


[convention] 71-71: Missing function or method docstring

(C0116)


[convention] 74-74: Missing function or method docstring

(C0116)


[convention] 84-84: Missing function or method docstring

(C0116)


[convention] 89-89: Missing function or method docstring

(C0116)


[convention] 104-104: Missing function or method docstring

(C0116)


[convention] 119-119: Missing function or method docstring

(C0116)


[convention] 134-134: Missing function or method docstring

(C0116)


[convention] 141-141: Missing function or method docstring

(C0116)


[convention] 146-146: Missing function or method docstring

(C0116)


[convention] 160-160: Missing function or method docstring

(C0116)


[convention] 163-163: Missing function or method docstring

(C0116)


[convention] 166-166: Missing function or method docstring

(C0116)


[convention] 171-171: Missing function or method docstring

(C0116)


[convention] 174-174: Missing function or method docstring

(C0116)


[convention] 199-199: Missing function or method docstring

(C0116)


[convention] 212-212: Missing function or method docstring

(C0116)


[convention] 232-232: Missing function or method docstring

(C0116)


[convention] 281-281: Missing function or method docstring

(C0116)


[convention] 300-300: Missing function or method docstring

(C0116)


[convention] 320-320: Missing function or method docstring

(C0116)


[convention] 333-333: Missing function or method docstring

(C0116)


[convention] 346-346: Missing function or method docstring

(C0116)


[convention] 359-359: Missing function or method docstring

(C0116)


[convention] 372-372: Missing function or method docstring

(C0116)


[convention] 385-385: Missing function or method docstring

(C0116)

⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Test Python 3.13 on windows-latest
🔇 Additional comments (22)
snapshots/countries/FR_972.json (1)

390-398: Rename looks coherent, but please double-check the historical start year for Victor Schoelcher Day

From 1984 onward the snapshot switches to "Victor Schoelcher Day".
Just ensure this holiday is not generated prior to 1984 in holidays/countries/france.py; otherwise the snapshot and generator will diverge.

No action required if the generator already enforces year >= 1984.

snapshots/countries/FR_973.json (2)

80-82: Good catch dropping the pre-1984 “Abolition of Slavery”.

The 1957 record now reads only "Whit Monday", matching the official timeline.


768-772: Mixed holiday names after 2019 – verify intent

For 2019 ("Abolition of Slavery; Whit Monday") and 2041 ("Abolition of Slavery; Whit Monday") the snapshot still concatenates both names, while earlier overlapping years were de-duplicated.

If the generator was changed to keep only "Abolition of Slavery" when it coincides with Whit Monday (as done for 1957), the snapshot will drift.

-    "2019-06-10": "Abolition of Slavery; Whit Monday",
+    "2019-06-10": "Abolition of Slavery",

Please confirm the expected wording in the generator and align snapshots accordingly.

Also applies to: 1028-1033

README.md (1)

586-586: Align France subdivisions list with code updates
The table now includes codes 6AE, PM, and TF among others. Verify these match the new ISO 3166-2 entries in your france.py module and maintain a logical order.

snapshots/countries/FR_971.json (2)

57-57: Verify removal of pre-1984 “Abolition of Slavery” entries
The holiday has been stripped from May 27 for 1954, 1965, and 1976—confirm this cut-off aligns with the historical recognition policy for Guadeloupe.

Also applies to: 194-194, 326-326


429-1367: Confirm consistent addition of “Victor Schoelcher Day”
The new July 21 entries have been added from 1984 through 2047. Please ensure the renaming and inclusion apply for all intended years and the date order remains correct in the serialized output.

snapshots/countries/FR_NC.json (2)

40-616: Review Annexation Day entries (1953–2003)
All September 24 holidays from 1953 to 2003 were renamed to “Annexation Day.” Verify there are no gaps or off-by-one errors in the year range and that this matches the logic in holidays/countries/france.py.


628-852: Confirm Citizenship Day restoration (2004–2023)
“Citizenship Day” is reintroduced on September 24 from 2004 through 2023. Ensure this aligns with the intended policy shift and corresponding test cases in tests/countries/test_france.py.

snapshots/countries/FR_MF.json (1)

658-661: Combined‐name entry is fine – just confirming intent

The 2012 row combines two holidays ("Abolition of Slavery; Whit Monday").
This mirrors other multi-holiday rows already present in the dataset (e.g. "Ascension Day; Labor Day" in 2008) and should be harmless, provided downstream consumers are known to handle the semicolon-separated form.

No action required.

snapshots/countries/FR_WF.json (2)

131-139: Summary vs. snapshot mismatch – “Feast of Saint Peter Chanel” still present

The PR description and AI summary claim the feast was removed and replaced by “Saints Peter and Paul Day”.
The snapshot, however, keeps the feast (e.g. 1962-04-28) and adds the new June-29 holiday.

Please double-check the intended rule set and adjust either the code or the snapshot so that documentation, summary and data are in sync.

Also applies to: 145-151

Likely an incorrect or invalid review comment.


113-117: Territory Day translation looks good

Renaming to “Territory Day” is reflected consistently across years.
No issues spotted here.

holidays/locale/uk/LC_MESSAGES/FR.po (1)

117-132: Nice work on fresh Ukrainian strings

New holidays are fully translated and use correct apostrophes (ʼ).
LGTM.

snapshots/countries/FR_6AE.json (1)

1-1285: Verify static snapshot matches dynamic output.
The JSON snapshot for subdivision “6AE” is extensive—ensure it fully aligns with the dynamic generation from France(subdiv='6AE') for years 1950–2050 to catch any missing or mismatched entries.

#!/usr/bin/env bash
# Validate snapshots/countries/FR_6AE.json against dynamic generation
python3 - << 'EOF'
import json
from holidays.countries.france import France

static = json.load(open('snapshots/countries/FR_6AE.json'))
errors = []
for date, name in static.items():
    dyn = France(subdiv='6AE', years=[int(date[:4])])
    if dyn.get(date) != name:
        errors.append((date, name, dyn.get(date)))
if errors:
    for d, s, dync in errors:
        print(f"Mismatch on {d}: static='{s}', dynamic='{dync}'")
    exit(1)
EOF
holidays/locale/en_US/LC_MESSAGES/FR.po (7)

17-27: Header metadata updated.
PO-Revision-Date, Last-Translator, and X-Generator have been bumped appropriately.


85-92: Add Victor Schoelcher & Abolition entries.
New translations for “Fête de Victor Schoelcher” and “Abolition de l’esclavage” are correctly mapped.


113-116: Add Territory Day.
“Fête du Territoire” → “Territory Day” is accurate.


117-120: Add May Day.
“1er mai” → “May Day” is correct.


121-124: Add Annexation Day.
“Fête de la prise de possession” → “Annexation Day” is accurate.


125-128: Add Matāri’i.
Native name preserved in translation.


129-132: Add Saints Peter and Paul Day.
“Saints Pierre et Paul” → “Saints Peter and Paul Day” is correct.

snapshots/countries/FR_PM.json (1)

1-1083: Verify static snapshot consistency for PM.
Ensure the JSON for subdivision “PM” matches the dynamic output of France(subdiv='PM') for 1950–2050.

#!/usr/bin/env bash
# Validate snapshots/countries/FR_PM.json against dynamic generation
python3 - << 'EOF'
import json
from holidays.countries.france import France

static = json.load(open('snapshots/countries/FR_PM.json'))
errors = []
for date, name in static.items():
    dyn = France(subdiv='PM', years=[int(date[:4])])
    if dyn.get(date) != name:
        errors.append((date, name, dyn.get(date)))
if errors:
    for d, s, dync in errors:
        print(f"Mismatch on {d}: static='{s}', dynamic='{dync}'")
    exit(1)
EOF
snapshots/countries/FR_TF.json (1)

1-1082: No actionable code to review

Only static snapshot data is present; nothing to critique at code level.

Copy link
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: 16

🔭 Outside diff range comments (3)
snapshots/countries/FR_WF.json (1)

131-138: Confirm new holiday pairs don’t collide

You’ve introduced a recurring “Saints Peter and Paul Day” (29 June) and renamed 29 July to “Territory Day”.
Please make sure:

  1. _populate_subdiv_wf_public_holidays() registers the new names only from 1962 forward (the snapshot shows that), and
  2. no other rule already uses 29 June/29 July, otherwise you’ll get duplicate-key merges when the class builds its dict.

A quick unit-level guard (e.g. assertNoDuplicates() like other tests) would future-proof this.

Also applies to: 135-138

holidays/countries/french_southern_territories.py (1)

20-30: Docstring grammar

“most islands doesn't have”

Should be “don’t”.
Tiny copy edit but improves perceived quality.

- Since most islands doesn't have a permanent population,
+ Since most islands don't have a permanent population,
holidays/locale/fr/LC_MESSAGES/FR.po (1)

117-132: Duplicated French msgids risk future collisions

"1er mai" and "Fête du Travail" both represent May Day.
Consider keeping only one canonical French label to prevent fuzzy matching issues down the line.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33202d2 and e308a68.

📒 Files selected for processing (21)
  • README.md (1 hunks)
  • holidays/countries/france.py (3 hunks)
  • holidays/countries/french_southern_territories.py (2 hunks)
  • holidays/locale/en_US/LC_MESSAGES/FR.po (3 hunks)
  • holidays/locale/fr/LC_MESSAGES/FR.po (3 hunks)
  • holidays/locale/uk/LC_MESSAGES/FR.po (3 hunks)
  • snapshots/countries/FR_6AE.json (1 hunks)
  • snapshots/countries/FR_971.json (70 hunks)
  • snapshots/countries/FR_972.json (70 hunks)
  • snapshots/countries/FR_973.json (1 hunks)
  • snapshots/countries/FR_974.json (0 hunks)
  • snapshots/countries/FR_976.json (0 hunks)
  • snapshots/countries/FR_BL.json (0 hunks)
  • snapshots/countries/FR_MF.json (39 hunks)
  • snapshots/countries/FR_NC.json (51 hunks)
  • snapshots/countries/FR_PF.json (26 hunks)
  • snapshots/countries/FR_PM.json (1 hunks)
  • snapshots/countries/FR_TF.json (1 hunks)
  • snapshots/countries/FR_WF.json (89 hunks)
  • tests/countries/test_france.py (5 hunks)
  • tests/countries/test_french_southern_territories.py (1 hunks)
💤 Files with no reviewable changes (3)
  • snapshots/countries/FR_974.json
  • snapshots/countries/FR_976.json
  • snapshots/countries/FR_BL.json
🧰 Additional context used
🧠 Learnings (1)
tests/countries/test_france.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.
🪛 Pylint (3.3.7)
holidays/countries/france.py

[convention] 25-25: Line too long (123/100)

(C0301)


[convention] 28-28: Line too long (126/100)

(C0301)


[convention] 29-29: Line too long (238/100)

(C0301)


[convention] 36-36: Line too long (148/100)

(C0301)


[convention] 39-39: Line too long (102/100)

(C0301)


[convention] 40-40: Line too long (148/100)

(C0301)


[convention] 41-41: Line too long (149/100)

(C0301)


[convention] 42-42: Line too long (151/100)

(C0301)


[convention] 43-43: Line too long (144/100)

(C0301)


[convention] 44-44: Line too long (103/100)

(C0301)


[convention] 45-45: Line too long (103/100)

(C0301)


[convention] 46-46: Line too long (124/100)

(C0301)


[convention] 47-47: Line too long (153/100)

(C0301)

tests/countries/test_france.py

[convention] 36-36: Missing function or method docstring

(C0116)


[convention] 39-39: Missing function or method docstring

(C0116)


[convention] 55-55: Missing function or method docstring

(C0116)


[convention] 71-71: Missing function or method docstring

(C0116)


[convention] 74-74: Missing function or method docstring

(C0116)


[convention] 84-84: Missing function or method docstring

(C0116)


[convention] 89-89: Missing function or method docstring

(C0116)


[convention] 104-104: Missing function or method docstring

(C0116)


[convention] 119-119: Missing function or method docstring

(C0116)


[convention] 134-134: Missing function or method docstring

(C0116)


[convention] 141-141: Missing function or method docstring

(C0116)


[convention] 146-146: Missing function or method docstring

(C0116)


[convention] 160-160: Missing function or method docstring

(C0116)


[convention] 163-163: Missing function or method docstring

(C0116)


[convention] 166-166: Missing function or method docstring

(C0116)


[convention] 171-171: Missing function or method docstring

(C0116)


[convention] 174-174: Missing function or method docstring

(C0116)


[convention] 199-199: Missing function or method docstring

(C0116)


[convention] 212-212: Missing function or method docstring

(C0116)


[convention] 232-232: Missing function or method docstring

(C0116)


[convention] 281-281: Missing function or method docstring

(C0116)


[convention] 300-300: Missing function or method docstring

(C0116)


[convention] 320-320: Missing function or method docstring

(C0116)


[convention] 333-333: Missing function or method docstring

(C0116)


[convention] 346-346: Missing function or method docstring

(C0116)


[convention] 359-359: Missing function or method docstring

(C0116)


[convention] 372-372: Missing function or method docstring

(C0116)


[convention] 385-385: Missing function or method docstring

(C0116)

⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Test Python 3.13 on windows-latest
🔇 Additional comments (16)
snapshots/countries/FR_973.json (1)

81-81: Double-check historical start year for “Abolition of Slavery”

The line now lists only “Whit Monday” on 1957-06-10.
Because the “Abolition of Slavery” observance for French Guiana is still present from 1984 onward, verify that the holiday was never legally observed before that year; otherwise you’ve silently dropped a valid holiday for 1957.

snapshots/countries/FR_WF.json (1)

752-758: String length & translation key consistency

Several renamed entries (“Territory Day”, “Saints Peter and Paul Day”) must exist in the .po files with identical strings; a one-char drift will break gettext fallback.

Run msguniq or the repo’s lint-messages target to be safe.

Also applies to: 754-757

tests/countries/test_french_southern_territories.py (1)

35-49: Good move to full name assertions

Switching to assertHolidays strengthens coverage by checking the French labels too.
Minor nit: keep the list alphabetised by date for fast visual diffing.

("2022-05-26", "Ascension"),
("2022-06-06", "Lundi de Pentecôte"),

No functional impact, just readability.

Likely an incorrect or invalid review comment.

snapshots/countries/FR_NC.json (1)

40-616: Confirm holiday renaming consistency
All September 24 entries from 1953–2003 are correctly labeled “Annexation Day” and reset to “Citizenship Day” from 2004 onward. Double-check that this aligns with the conditional logic in holidays/countries/france.py and the localization keys.

Also applies to: 628-663

snapshots/countries/FR_PF.json (1)

970-1320: Confirm addition of 'Matāri'i' recurring holiday.
New Matāri'i entries on November 20 have been correctly inserted for 2025–2050 in the French Polynesia snapshot, preserving chronological order and matching the updated holiday logic.

snapshots/countries/FR_971.json (2)

57-57: Abolition of Slavery removal is correct.
The standalone "Abolition of Slavery" suffix has been removed from the Ascension Day entries (e.g., 1954-05-27 and 1965-05-27), aligning with the refined holiday rules for Guadeloupe.

Also applies to: 194-194


429-1410: Victor Schoelcher Day rename verified.
The former "Feast of Victor Schoelcher" entries have been consistently renamed to "Victor Schoelcher Day" from 1984 onward across all relevant dates, matching the subdivision’s updated holiday definitions.

snapshots/countries/FR_972.json (2)

24-34: Double-check early Abolition-of-Slavery removals

Pre-1984 entries for 22 May have been stripped (now only Ascension/Whit Monday remain). That matches the stated historical start-year (1984), but please verify no stray “Abolition of Slavery” strings still lurk elsewhere in the 1950-1983 window.


389-397: Year-of-enactment sanity check

Lines 389-397 introduce both
"1984-05-22": "Abolition of Slavery"
"1984-07-21": "Victor Schoelcher Day"

Cross-reference the legal texts (loi n° 83-550 & decree 1987-100) to confirm Martinique’s first effective year really is 1984 (not 1983). A one-year shift would silently break downstream tests.

holidays/locale/uk/LC_MESSAGES/FR.po (1)

117-132: Possible duplication of May-Day strings

"Fête du Travail" already maps to “День праці”; new entry "1er mai" maps to “Перше травня”. Unless the library purposely emits both French aliases, this creates redundant translations.

snapshots/countries/FR_MF.json (2)

658-662: Mixed holiday name separator – verify downstream parsers accept ;

"Abolition of Slavery; Whit Monday" uses a semicolon to concatenate two holidays that fall on the same date.
Elsewhere (e.g. 2008-05-01 "Ascension Day; Labor Day") the same pattern appears, but some consumers of the snapshot derive a unique key by splitting on , or / only.

Double-check that:

  1. holidays.__init__.HolidayBase.get_list() correctly splits on ;.
  2. No client code assumes a single name per date.

If unsure, add a tiny unit test for the parser.


660-661: New “Victor Schoelcher Day” — make sure translation is aligned

FR.po still lists the msgid “Fête de Victor Schoelcher” (French) but no English equivalent exists in en_US.po.

If the canonical English name is “Victor Schoelcher Day”, add it to en_US.po to keep message-ID symmetry or we’ll end up with mixed naming across languages.

Also applies to: 671-674, 685-688

holidays/countries/french_southern_territories.py (2)

34-35: default_language must be in supported_languages

You already added "fr" to supported_languages, good catch.
Just flagging this because mismatches silently break localisation later.


39-43: Subclass correctly forces subdiv – nice

Overriding _populate_public_holidays() with self.subdiv = "TF" is the cleanest way to reuse France logic while pinning the subdivision.
LGTM.

holidays/locale/fr/LC_MESSAGES/FR.po (1)

15-28: Metadata looks fresh – thanks

Updated revision & generator info noted.

holidays/locale/en_US/LC_MESSAGES/FR.po (1)

117-124: Plural-forms missing

New msgids (1er mai, Fête de la prise de possession) may appear with plural counts elsewhere. Add a Plural-Forms: header or explicitly mark n/a if singular-only.

Copy link
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: 6

🔭 Outside diff range comments (2)
snapshots/countries/FR_971.json (1)

776-777: Mixed-label entry (“Ascension Day; Labor Day”) – verify concatenation order

Line 776 combines Ascension and Labor Day on 1 May 2008.
While historically accurate for Guadeloupe, concatenation order should be deterministic across the dataset (Labor Day; Ascension Day vs Ascension Day; Labor Day). If another subdivision uses the opposite order, consider normalising to avoid brittle diff noise.

snapshots/countries/FR_PF.json (1)

318-331: Inconsistent snapshot: Deprecated PF holidays still present
The PR objectives mention removing “Missionary Day” and “Internal Autonomy Day” for French Polynesia, but this snapshot still lists them (e.g., lines 318–331 and 412–440). Please confirm if those deletions should be applied here.

Also applies to: 412-440

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33202d2 and e308a68.

📒 Files selected for processing (21)
  • README.md (1 hunks)
  • holidays/countries/france.py (3 hunks)
  • holidays/countries/french_southern_territories.py (2 hunks)
  • holidays/locale/en_US/LC_MESSAGES/FR.po (3 hunks)
  • holidays/locale/fr/LC_MESSAGES/FR.po (3 hunks)
  • holidays/locale/uk/LC_MESSAGES/FR.po (3 hunks)
  • snapshots/countries/FR_6AE.json (1 hunks)
  • snapshots/countries/FR_971.json (70 hunks)
  • snapshots/countries/FR_972.json (70 hunks)
  • snapshots/countries/FR_973.json (1 hunks)
  • snapshots/countries/FR_974.json (0 hunks)
  • snapshots/countries/FR_976.json (0 hunks)
  • snapshots/countries/FR_BL.json (0 hunks)
  • snapshots/countries/FR_MF.json (39 hunks)
  • snapshots/countries/FR_NC.json (51 hunks)
  • snapshots/countries/FR_PF.json (26 hunks)
  • snapshots/countries/FR_PM.json (1 hunks)
  • snapshots/countries/FR_TF.json (1 hunks)
  • snapshots/countries/FR_WF.json (89 hunks)
  • tests/countries/test_france.py (5 hunks)
  • tests/countries/test_french_southern_territories.py (1 hunks)
💤 Files with no reviewable changes (3)
  • snapshots/countries/FR_BL.json
  • snapshots/countries/FR_974.json
  • snapshots/countries/FR_976.json
🧰 Additional context used
🧠 Learnings (1)
tests/countries/test_france.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.
🪛 Pylint (3.3.7)
tests/countries/test_france.py

[convention] 36-36: Missing function or method docstring

(C0116)


[convention] 39-39: Missing function or method docstring

(C0116)


[convention] 55-55: Missing function or method docstring

(C0116)


[convention] 71-71: Missing function or method docstring

(C0116)


[convention] 74-74: Missing function or method docstring

(C0116)


[convention] 84-84: Missing function or method docstring

(C0116)


[convention] 89-89: Missing function or method docstring

(C0116)


[convention] 104-104: Missing function or method docstring

(C0116)


[convention] 119-119: Missing function or method docstring

(C0116)


[convention] 134-134: Missing function or method docstring

(C0116)


[convention] 141-141: Missing function or method docstring

(C0116)


[convention] 146-146: Missing function or method docstring

(C0116)


[convention] 160-160: Missing function or method docstring

(C0116)


[convention] 163-163: Missing function or method docstring

(C0116)


[convention] 166-166: Missing function or method docstring

(C0116)


[convention] 171-171: Missing function or method docstring

(C0116)


[convention] 174-174: Missing function or method docstring

(C0116)


[convention] 199-199: Missing function or method docstring

(C0116)


[convention] 212-212: Missing function or method docstring

(C0116)


[convention] 232-232: Missing function or method docstring

(C0116)


[convention] 281-281: Missing function or method docstring

(C0116)


[convention] 300-300: Missing function or method docstring

(C0116)


[convention] 320-320: Missing function or method docstring

(C0116)


[convention] 333-333: Missing function or method docstring

(C0116)


[convention] 346-346: Missing function or method docstring

(C0116)


[convention] 359-359: Missing function or method docstring

(C0116)


[convention] 372-372: Missing function or method docstring

(C0116)


[convention] 385-385: Missing function or method docstring

(C0116)

holidays/countries/france.py

[convention] 25-25: Line too long (123/100)

(C0301)


[convention] 28-28: Line too long (126/100)

(C0301)


[convention] 29-29: Line too long (238/100)

(C0301)


[convention] 36-36: Line too long (148/100)

(C0301)


[convention] 39-39: Line too long (102/100)

(C0301)


[convention] 40-40: Line too long (148/100)

(C0301)


[convention] 41-41: Line too long (149/100)

(C0301)


[convention] 42-42: Line too long (151/100)

(C0301)


[convention] 43-43: Line too long (144/100)

(C0301)


[convention] 44-44: Line too long (103/100)

(C0301)


[convention] 45-45: Line too long (103/100)

(C0301)


[convention] 46-46: Line too long (124/100)

(C0301)


[convention] 47-47: Line too long (153/100)

(C0301)

⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Test Python 3.13 on windows-latest
🔇 Additional comments (22)
snapshots/countries/FR_973.json (1)

81-81: Confirm removal of “Abolition of Slavery” before 1984

Line 81 now records only “Whit Monday”.
That implicitly drops the earlier composite entry (“Abolition of Slavery; Whit Monday”) for 1957. Please double-check that 10 June 1957 is not officially commemorated in French Guiana for the abolition event (most sources place the observance on 10 June but starting 1984).
If this was intentional, no change needed; otherwise re-insert the abolition holiday for 1957–1983.

snapshots/countries/FR_971.json (2)

425-434: New “Victor Schoelcher Day” entries – sanity-check fixed date logic

Starting 1984 the snapshot introduces "Victor Schoelcher Day" on 21 July.
If the upstream generator simply appends a fixed-date holiday, great. Please ensure:

  1. The generator only adds it from 1984 forward.
  2. No duplicate exists when 21 July collides with a weekend and an observed rule is later applied.

Good to see the abolition day separated from this commemoration.


57-58: Let’s compute Ascension Day directly (without external libs) to verify those dates fall on a Thursday 39 days after Easter:

#!/bin/bash
python3 - <<'PY'
import datetime

def easter_date(year):
    # Anonymous Gregorian algorithm
    a = year % 19
    b = year // 100
    c = year % 100
    d = b // 4
    e = b % 4
    f = (b + 8) // 25
    g = (b - f + 1) // 3
    h = (19*a + b - d - g + 15) % 30
    i = c // 4
    k = c % 4
    l = (32 + 2*e + 2*i - h - k) % 7
    m = (a + 11*h + 22*l) // 451
    month = (h + l - 7*m + 114) // 31
    day = ((h + l - 7*m + 114) % 31) + 1
    return datetime.date(year, month, day)

for y in (1954, 1965, 1976):
    eas = easter_date(y)
    asc = eas + datetime.timedelta(days=39)
    print(f"{y}: Ascension = {asc} (weekday {asc.weekday()})")
PY
tests/countries/test_french_southern_territories.py (1)

35-49: Great improvement – test now validates French labels

Switching the 2022 assertions to the French wording matches the default locale produced by HolidaysTF. The list is exhaustive and in chronological order – nice!

No action required.

snapshots/countries/FR_WF.json (2)

135-1342: Add new holiday: Saints Peter and Paul Day
The snapshot now includes “Saints Peter and Paul Day” on June 29 from 1962 through 2050. Confirm that locale translation files and unit tests have been updated to cover this new recurring holiday.


137-1344: Rename holiday: Territory Day
All July 29 entries have been renamed to “Territory Day” replacing the old “Festival of the Territory” label. Verify that translations and tests reflect this rename consistently.

snapshots/countries/FR_PF.json (1)

970-1320: Add new holiday: Matāri'i
Introduced “Matāri'i” on November 20 starting in 2025 and recurring through 2050 for French Polynesia. Ensure locale files and tests verify this addition.

README.md (1)

586-588: Doc update: France subdivisions expanded
The new subdivision codes for Moselle, Alsace, DOM/TOM, etc., look comprehensive and align with ISO 3166-2. Please double-check that these codes exactly match those defined in holidays/countries/france.py.

snapshots/countries/FR_NC.json (1)

40-616: Holiday rename: 24 September pre-2004 updated to Annexation Day
All instances from 1953 through 2003 were correctly changed from “Citizenship Day” to “Annexation Day.” Ensure that the corresponding logic in france.py, the translation files, and the test suite are in sync with this renaming.

snapshots/countries/FR_972.json (2)

28-256: Verify moveable feast date adjustments
The entries for Ascension Day (“1952-05-22”) and Whit Monday (“1961-05-22”, “1972-05-22”) have been shifted. Please confirm these align with 39 and 50 days after Easter respectively.

#!/bin/bash
# Verify Easter-based feast dates in FR_972.json
python3 - << 'EOF'
import json, datetime
from dateutil.easter import easter
data = json.load(open("snapshots/countries/FR_972.json"))
for year, expected in [(1952,"Ascension Day"),(1961,"Whit Monday"),(1972,"Whit Monday")]:
    eas = easter(year)
    asc = eas + datetime.timedelta(days=39)
    wm  = eas + datetime.timedelta(days=50)
    actual = data[f"{year}-{asc:%m-%d}"] if expected=="Ascension Day" else data[f"{year}-{wm:%m-%d}"]
    print(year, expected, "->", asc if expected=="Ascension Day" else wm, actual)
EOF

394-1310: Approve ‘Victor Schoelcher Day’ additions from 1984–2050
All “Victor Schoelcher Day” entries on July 21 have been added chronologically, matching the new holiday logic.

Run a quick grep to ensure no earlier occurrences slip in:

rg -n '"Victor Schoelcher Day"' snapshots/countries/FR_972.json
snapshots/countries/FR_MF.json (2)

658-660: Let’s check if “05-28” shows up for any other year in FR_MF.json:

rg -n '05-28' snapshots/countries/FR_MF.json

671-1154: ```shell
rg -n '"2050-05-28": "Abolition of Slavery"' snapshots/countries/FR_MF.json
rg -n '"2050-07-21": "Victor Schoelcher Day"' snapshots/countries/FR_MF.json


</details>
<details>
<summary>snapshots/countries/FR_PM.json (1)</summary>

`1-1082`: **Snapshot looks mechanically correct, but please sanity-check edge-case years.**

Tiny historical glitches (e.g. Victory Day disappearance 1960-1981, dual-holiday collisions like *“Ascension Day; Victory Day”*) are notoriously easy to get wrong.  
Before we freeze this 100-year payload, can you run an automated diff against the reference algorithm to confirm:

1. All 8 May entries exist **only** in 1953-1959 and ≥ 1982.  
2. Any date string that contains “;” corresponds to a genuine same-day collision.

Happy to script this if useful.

</details>
<details>
<summary>holidays/locale/fr/LC_MESSAGES/FR.po (2)</summary>

`85-92`: **Empty `msgstr` for new strings – intentional?**

Lines 85-92 introduce *Fête de Victor Schoelcher* & *Abolition de l'esclavage* but leave `msgstr` blank.  
If the intent is to reuse the French `msgid` at runtime, consider adding `#, fuzzy` to silence Poedit warnings, or copy `msgid` into `msgstr`.

---

`15-27`: **Consider adding `Plural-Forms` for completeness.**

French compiles without it, but the header is recommended:

`"Plural-Forms: nplurals=2; plural=(n > 1);\n"`

Keeps tooling quiet and consistent with other *.po* files.



<details>
<summary>⛔ Skipped due to learnings</summary>

Learnt from: PPsyrius
PR: #2537
File: holidays/locale/sv_FI/LC_MESSAGES/AX.po:17-27
Timestamp: 2025-05-10T04:34:02.406Z
Learning: The Plural-Forms header isn't used in .po file generation for the holidays project and doesn't need to be manually added to localization files.


</details>

</details>
<details>
<summary>snapshots/countries/FR_6AE.json (1)</summary>

`1-14`: **Dataset includes Good Friday & St Stephen – nice!**

ALS/6AE regional quirks captured correctly; no issues spotted.

</details>
<details>
<summary>snapshots/countries/FR_TF.json (1)</summary>

`1-1083`: **Well-structured snapshot data.**

The JSON file correctly captures French Southern and Antarctic Lands holidays from 1950-2050. The intermittent Victory Day observance (1953-1959, 1982+) aligns with the historical implementation in the main France class.

</details>
<details>
<summary>holidays/locale/en_US/LC_MESSAGES/FR.po (1)</summary>

`17-131`: **Translation updates look good.**

The refinements to holiday names improve consistency, and the new entries support the expanded holiday set. All changes maintain proper gettext format.

</details>
<details>
<summary>tests/countries/test_france.py (2)</summary>

`23-27`: **Comprehensive test setup.**

The expanded year range (1803-2050) and subdivision coverage properly validates the historical accuracy improvements in the main implementation.

---

`84-397`: **Excellent historical test coverage.**

The dedicated test methods for each holiday with precise year ranges ensure the historical accuracy improvements are properly validated. The subdivision-specific tests are particularly thorough.

</details>
<details>
<summary>holidays/countries/france.py (1)</summary>

`60-107`: **Subdivision modernization well-executed.**

The transition to numeric/alphanumeric codes with comprehensive aliases ensures backward compatibility while modernizing the codebase.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
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: 4

🔭 Outside diff range comments (1)
holidays/locale/th/LC_MESSAGES/TF.po (1)

13-29: Empty template – consider dropping it

TF.po contains only metadata. If TF re-uses all French msgids, the file is redundant and will quickly fall out of sync. Either:

  1. remove the file and rely on the FR catalog, or
  2. add TF-specific entries now to justify its presence.

Keeps the l10n tree lean.

♻️ Duplicate comments (1)
tests/countries/test_france.py (1)

71-73: Deprecation message still hard-coded

Upstream learning notes say the generic string is standard; if that ever changes the test suite will break globally.
Maybe assert on warnings.catch_warnings(record=True) to capture real message instead – future-proof without losing coverage.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c1047d9 and ccdd0ce.

📒 Files selected for processing (6)
  • README.md (1 hunks)
  • holidays/countries/france.py (3 hunks)
  • holidays/locale/th/LC_MESSAGES/FR.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/TF.po (1 hunks)
  • tests/countries/test_france.py (6 hunks)
  • tests/countries/test_french_southern_territories.py (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:12:57.410Z
Learning: In the France holidays implementation, subdivisions like "GES" and "Metropole" that covered multiple departments with different holiday rules are completely deprecated rather than aliased, because aliasing them to a subset (like Alsace-Moselle) would provide incomplete or incorrect holiday data for the other covered regions. Complete deprecation is preferred over partial/incorrect data coverage.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.159Z
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.
tests/countries/test_france.py (2)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_france.py:70-73
Timestamp: 2025-06-18T10:38:45.670Z
Learning: In the holidays library, the `assertDeprecatedSubdivisions` method uses a generic hard-coded message ("This subdivision is deprecated and will be removed") for all deprecated subdivision tests. This is the library-wide standard pattern, not specific to individual countries.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.
holidays/countries/france.py (8)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.159Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:300-319
Timestamp: 2025-06-18T10:21:01.353Z
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: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:184-206
Timestamp: 2025-06-18T10:58:28.041Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:12:57.410Z
Learning: In the France holidays implementation, subdivisions like "GES" and "Metropole" that covered multiple departments with different holiday rules are completely deprecated rather than aliased, because aliasing them to a subset (like Alsace-Moselle) would provide incomplete or incorrect holiday data for the other covered regions. Complete deprecation is preferred over partial/incorrect data coverage.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/french_southern_territories.py:41-44
Timestamp: 2025-06-18T10:07:58.769Z
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: PPsyrius
PR: vacanza/holidays#2615
File: tests/countries/test_anguilla.py:20-24
Timestamp: 2025-06-16T15:48:33.889Z
Learning: The holidays project uses `make pre-commit` test which includes `ruff` as the primary linter. If `ruff` passes, then Pylint warnings that don't appear in `ruff` are considered acceptable and can be ignored.
Learnt from: PPsyrius
PR: vacanza/holidays#2637
File: holidays/countries/singapore.py:49-50
Timestamp: 2025-06-16T11:17:34.653Z
Learning: For the vacanza/holidays project, defer to ruff's line length rules rather than pylint's C0301 warnings. If ruff passes in pre-commit tests, line length is acceptable regardless of pylint warnings about exceeding 100 characters.
🪛 Pylint (3.3.7)
tests/countries/test_french_southern_territories.py

[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 51-51: Missing function or method docstring

(C0116)


[convention] 66-66: Missing function or method docstring

(C0116)


[convention] 82-82: Missing function or method docstring

(C0116)


[convention] 98-98: Missing function or method docstring

(C0116)

tests/countries/test_france.py

[convention] 36-36: Missing function or method docstring

(C0116)


[convention] 39-39: Missing function or method docstring

(C0116)


[convention] 55-55: Missing function or method docstring

(C0116)


[convention] 71-71: Missing function or method docstring

(C0116)


[convention] 74-74: Missing function or method docstring

(C0116)


[convention] 84-84: Missing function or method docstring

(C0116)


[convention] 89-89: Missing function or method docstring

(C0116)


[convention] 104-104: Missing function or method docstring

(C0116)


[convention] 119-119: Missing function or method docstring

(C0116)


[convention] 134-134: Missing function or method docstring

(C0116)


[convention] 141-141: Missing function or method docstring

(C0116)


[convention] 146-146: Missing function or method docstring

(C0116)


[convention] 160-160: Missing function or method docstring

(C0116)


[convention] 163-163: Missing function or method docstring

(C0116)


[convention] 166-166: Missing function or method docstring

(C0116)


[convention] 171-171: Missing function or method docstring

(C0116)


[convention] 174-174: Missing function or method docstring

(C0116)


[convention] 199-199: Missing function or method docstring

(C0116)


[convention] 212-212: Missing function or method docstring

(C0116)


[convention] 232-232: Missing function or method docstring

(C0116)


[convention] 281-281: Missing function or method docstring

(C0116)


[convention] 300-300: Missing function or method docstring

(C0116)


[convention] 320-320: Missing function or method docstring

(C0116)


[convention] 333-333: Missing function or method docstring

(C0116)


[convention] 346-346: Missing function or method docstring

(C0116)


[convention] 359-359: Missing function or method docstring

(C0116)


[convention] 372-372: Missing function or method docstring

(C0116)


[convention] 385-385: Missing function or method docstring

(C0116)


[convention] 461-461: Missing function or method docstring

(C0116)

holidays/countries/france.py

[convention] 25-25: Line too long (123/100)

(C0301)


[convention] 28-28: Line too long (126/100)

(C0301)


[convention] 29-29: Line too long (238/100)

(C0301)


[convention] 36-36: Line too long (148/100)

(C0301)


[convention] 39-39: Line too long (102/100)

(C0301)


[convention] 40-40: Line too long (148/100)

(C0301)


[convention] 41-41: Line too long (149/100)

(C0301)


[convention] 42-42: Line too long (151/100)

(C0301)


[convention] 43-43: Line too long (144/100)

(C0301)


[convention] 44-44: Line too long (103/100)

(C0301)


[convention] 45-45: Line too long (103/100)

(C0301)


[convention] 46-46: Line too long (124/100)

(C0301)


[convention] 47-47: Line too long (153/100)

(C0301)

🔇 Additional comments (5)
README.md (1)

591-595: 👍 Thai language correctly added

Nice catch adding th to both France and TF rows; keeps docs consistent.

holidays/locale/th/LC_MESSAGES/FR.po (1)

126-133: Translation duplication check

Good to see TF-only holidays (e.g., “Fête du Territoire”) translated here. Verify no later duplicate keys exist in TF.po to avoid msgfmt warnings.

tests/countries/test_french_southern_territories.py (1)

35-49: Add Good Friday for completeness?

2024-03-29 (Good Friday) is a holiday in TF but is not asserted here, while later localisation tests cover it for 2022. Including it keeps coverage symmetric across years.

holidays/countries/france.py (2)

78-107: Alias also listed as deprecated – verify intent

"Saint-Barthélémy" appears both in subdivisions_aliases and _deprecated_subdivisions.
If HolidayBase applies aliases before deprecation checks, this dual listing may silently suppress the deprecation warning; if it does the other way around, the alias will never be reached.

Please double-check the call order and keep the name in only one place (alias or deprecated) to avoid contradictory behaviour.


212-214: Ensure helper methods exist

These blocks rely on project-wide helpers:

  • _add_holiday_24_days_prior_easter (Mi-Carême)
  • _add_saints_peter_and_paul_day

To avoid runtime errors, confirm they’re defined somewhere in ChristianHolidays or another mix-in.

#!/bin/bash
# Verify helper definitions exist in the codebase.
rg --no-heading --line-number $'def _add_holiday_24_days_prior_easter' || echo "NOT FOUND: _add_holiday_24_days_prior_easter"
rg --no-heading --line-number $'def _add_saints_peter_and_paul_day' || echo "NOT FOUND: _add_saints_peter_and_paul_day"

Also applies to: 328-330

Copy link
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

🔭 Outside diff range comments (2)
holidays/locale/th/LC_MESSAGES/PM.po (1)

15-29: Populate translation entries
The Thai locale PO file currently only contains metadata headers. Please extract and add msgid/msgstr pairs for all Saint Pierre and Miquelon holiday strings to enable proper localization.

Let me know if you’d like help populating or generating the translation template.

holidays/locale/uk/LC_MESSAGES/PM.po (1)

15-29: Add Ukrainian translations
The Ukrainian PO file is empty aside from headers. Please extract and fill in msgid/msgstr pairs for all relevant holiday names.

I can assist in generating the template with extracted entries if needed.

♻️ Duplicate comments (1)
tests/countries/test_french_southern_territories.py (1)

51-112: L10n test duplication could be reduced.

These four test methods share the same structure and could benefit from parametrization.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ccdd0ce and 4291ff3.

📒 Files selected for processing (12)
  • README.md (3 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/countries/france.py (3 hunks)
  • holidays/countries/saint_pierre_and_miquelon.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/PM.po (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/PM.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/PM.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/PM.po (1 hunks)
  • holidays/registry.py (1 hunks)
  • snapshots/countries/PM_COMMON.json (1 hunks)
  • tests/countries/test_french_southern_territories.py (2 hunks)
  • tests/countries/test_saint_pierre_and_miquelon.py (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:12:57.410Z
Learning: In the France holidays implementation, subdivisions like "GES" and "Metropole" that covered multiple departments with different holiday rules are completely deprecated rather than aliased, because aliasing them to a subset (like Alsace-Moselle) would provide incomplete or incorrect holiday data for the other covered regions. Complete deprecation is preferred over partial/incorrect data coverage.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.159Z
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.
snapshots/countries/PM_COMMON.json (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2407
File: snapshots/countries/TL_COMMON.json:7-7
Timestamp: 2025-04-03T05:59:57.480Z
Learning: In the holidays project, snapshot files (like snapshots/countries/TL_COMMON.json) are auto-generated when running `make snapshot` and should not be manually edited. Semicolons (;) in holiday entries are used as separators when multiple holidays occur on the same date.
README.md (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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.
tests/countries/test_french_southern_territories.py (2)
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:85-86
Timestamp: 2025-04-05T04:29:38.042Z
Learning: For testing holiday implementations in the vacanza/holidays repository, recommend using `from tests.common import CommonCountryTests` as the base class instead of directly using `unittest.TestCase` to maintain consistency with project conventions and leverage common test utilities.
holidays/countries/france.py (8)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.159Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:300-319
Timestamp: 2025-06-18T10:21:01.353Z
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: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:184-206
Timestamp: 2025-06-18T10:58:28.041Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:12:57.410Z
Learning: In the France holidays implementation, subdivisions like "GES" and "Metropole" that covered multiple departments with different holiday rules are completely deprecated rather than aliased, because aliasing them to a subset (like Alsace-Moselle) would provide incomplete or incorrect holiday data for the other covered regions. Complete deprecation is preferred over partial/incorrect data coverage.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/french_southern_territories.py:41-44
Timestamp: 2025-06-18T10:07:58.769Z
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: PPsyrius
PR: vacanza/holidays#2615
File: tests/countries/test_anguilla.py:20-24
Timestamp: 2025-06-16T15:48:33.889Z
Learning: The holidays project uses `make pre-commit` test which includes `ruff` as the primary linter. If `ruff` passes, then Pylint warnings that don't appear in `ruff` are considered acceptable and can be ignored.
Learnt from: PPsyrius
PR: vacanza/holidays#2637
File: holidays/countries/singapore.py:49-50
Timestamp: 2025-06-16T11:17:34.653Z
Learning: For the vacanza/holidays project, defer to ruff's line length rules rather than pylint's C0301 warnings. If ruff passes in pre-commit tests, line length is acceptable regardless of pylint warnings about exceeding 100 characters.
🪛 Pylint (3.3.7)
tests/countries/test_saint_pierre_and_miquelon.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 24-24: Missing class docstring

(C0115)


[warning] 26-26: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintPierreAndMiquelon.setUpClass' method

(W0221)


[convention] 29-29: Missing function or method docstring

(C0116)


[convention] 32-32: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 51-51: Missing function or method docstring

(C0116)


[convention] 66-66: Missing function or method docstring

(C0116)


[convention] 82-82: Missing function or method docstring

(C0116)


[convention] 98-98: Missing function or method docstring

(C0116)

holidays/countries/saint_pierre_and_miquelon.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 39-39: Missing class docstring

(C0115)


[convention] 43-43: Missing class docstring

(C0115)


[convention] 47-47: Missing class docstring

(C0115)

tests/countries/test_french_southern_territories.py

[convention] 24-24: Missing class docstring

(C0115)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 51-51: Missing function or method docstring

(C0116)


[convention] 66-66: Missing function or method docstring

(C0116)


[convention] 82-82: Missing function or method docstring

(C0116)


[convention] 98-98: Missing function or method docstring

(C0116)

holidays/countries/france.py

[convention] 25-25: Line too long (123/100)

(C0301)


[convention] 28-28: Line too long (126/100)

(C0301)


[convention] 29-29: Line too long (238/100)

(C0301)


[convention] 36-36: Line too long (148/100)

(C0301)


[convention] 39-39: Line too long (102/100)

(C0301)


[convention] 40-40: Line too long (148/100)

(C0301)


[convention] 41-41: Line too long (149/100)

(C0301)


[convention] 42-42: Line too long (151/100)

(C0301)


[convention] 43-43: Line too long (144/100)

(C0301)


[convention] 44-44: Line too long (103/100)

(C0301)


[convention] 45-45: Line too long (103/100)

(C0301)


[convention] 46-46: Line too long (124/100)

(C0301)


[convention] 47-47: Line too long (153/100)

(C0301)

⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Test Python 3.13 on windows-latest
🔇 Additional comments (17)
holidays/registry.py (1)

168-168: Well-placed registry entry
The new "saint_pierre_and_miquelon" mapping correctly follows alphabetical order and aligns with other COUNTRIES entries.

holidays/countries/__init__.py (1)

165-170: Imports for Saint Pierre and Miquelon
The import block correctly exposes SaintPierreAndMiquelon, PM, SPM, and HolidaysPM following the established pattern.

holidays/locale/fr/LC_MESSAGES/PM.po (1)

15-29: Let’s confirm whether the French PO file contains any translation entries beyond its header.

#!/bin/bash
# Locate the French .po file
FILE=$(find . -type f -path "./holidays/locale/fr/LC_MESSAGES/*.po" | head -n1)
if [ -z "$FILE" ]; then
  echo "ERROR: No French PO file found under holidays/locale/fr/LC_MESSAGES/"
  exit 1
fi
echo "Checking file: $FILE"
# List all msgid lines (including header)
grep -n '^msgid ' "$FILE"
holidays/locale/en_US/LC_MESSAGES/PM.po (1)

15-29: Empty PO stub – intentional?

Header looks fine, but there are no actual msgid/msgstr pairs.
If every holiday name is identical to the English source you can leave it, otherwise translations are missing.

Would you like me to scan the codebase for _("…") occurrences scoped to PM and report any untranslated strings?

snapshots/countries/PM_COMMON.json (1)

1-1082: Snapshot file – no manual review needed

Generated snapshot looks syntactically valid; nothing to flag.

README.md (4)

585-587: France row LGTM

Subdivision list and Thai (th) language addition align with the code changes.


593-595: TF language list updated correctly

The extra Thai localisation matches the new PO file.


1165-1169: PM entry position

Saint Pierre and Miquelon row appears after other Saint … rows – alphabetical order preserved.
Content itself checks out.


108-108: Let’s verify the actual supported country count by inspecting the holidays/countries package:

#!/bin/bash
python3 - <<'PY'
import pkgutil, holidays.countries
# Count all modules in holidays/countries (excludes __init__.py automatically)
count = sum(1 for _ in pkgutil.iter_modules(holidays.countries.__path__))
print(count)
PY
holidays/countries/saint_pierre_and_miquelon.py (1)

34-36: Set subdiv once in __init__ instead

Assigning self.subdiv = "PM" inside every _populate_public_holidays call works but repeats on yearly rebuilds.

-class HolidaysPM(France):
+class HolidaysPM(France):
     ...
-    def _populate_public_holidays(self) -> None:
-        self.subdiv = "PM"
-        super()._populate_public_holidays()
+    def __init__(self, *args, **kwargs):
+        kwargs.setdefault("subdiv", "PM")
+        super().__init__(*args, **kwargs)

Keeps the attribute stable and avoids mutating state mid-population.

⛔ Skipped due to learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:184-206
Timestamp: 2025-06-18T10:58:28.041Z
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
PR: vacanza/holidays#2642
File: holidays/countries/french_southern_territories.py:41-44
Timestamp: 2025-06-18T10:07:58.769Z
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
PR: vacanza/holidays#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.
tests/countries/test_saint_pierre_and_miquelon.py (1)

26-28: Signature mismatch warning – double-check base

Static analysis flags setUpClass arg count.
Existing test suites often expect setUpClass(cls_under_test); if CI passes you can ignore, otherwise adjust.

tests/countries/test_french_southern_territories.py (1)

35-49: Solid test enhancement with name validation.

The upgrade from just date checking to validating both dates and French names strengthens the test coverage nicely.

holidays/countries/france.py (5)

56-58: Well-researched start year adjustment.

The shift to 1803 with proper legal citations strengthens historical accuracy.


60-100: Clean subdivision modernization with solid backward compatibility.

The migration to ISO standard codes is well-structured, and the alias mappings ensure existing code won't break.


178-182: Proper deprecated subdivision routing.

The explicit conditionals correctly maintain backward compatibility for deprecated subdivision names.


184-206: Framework-constrained duplication is acceptable.

The identical implementations for Moselle and Alsace subdivisions are a known limitation.


114-177: Impressive historical accuracy with year-specific implementations.

Each holiday's establishment date and any subsequent changes are meticulously documented with legal references. The varying Labor Day names across different periods and the gaps in Victory Day and Whit Monday observance show excellent attention to detail.

Copy link
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: 3

🔭 Outside diff range comments (8)
holidays/locale/th/LC_MESSAGES/PM.po (1)

15-29: Add “Plural-Forms” header to prevent runtime i18n failures

The header block lacks the mandatory Plural-Forms: metadata.
Without it, GNU gettext falls back to default plural rules (which are wrong for Thai) and will raise warnings in strict runtimes.

 "Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
 "Generated-By: Lingva 5.0.6\n"

Thai has a single plural form, so the above rule is sufficient.
Replicate the same fix in every new th PO file added by this PR.

holidays/locale/fr/LC_MESSAGES/WF.po (1)

15-29: Missing “Plural-Forms” header breaks French pluralisation

Even though French uses default rules, the header must still be explicit for completeness and linting tools.

 "Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
 "Generated-By: Lingva 5.0.6\n"
holidays/locale/uk/LC_MESSAGES/WF.po (1)

15-29: Ukrainian PO header: add correct 3-form plural rule

Ukrainian requires three plural forms; omitting this header will make gettext choose the English rule and yield wrong strings.

 "Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : "
+"(n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2));\n"
 "Generated-By: Lingva 5.0.6\n"
holidays/locale/uk/LC_MESSAGES/PM.po (1)

15-29: Add “Plural-Forms” header for Ukrainian

Same missing metadata as in the other Ukrainian file – copy the 3-form rule.

 "Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : "
+"(n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2));\n"
 "Generated-By: Lingva 5.0.6\n"
holidays/locale/th/LC_MESSAGES/WF.po (1)

15-29: Plural-Forms header is missing for Thai

Repeat the fix applied to the PM Thai file to ensure correct plural handling.

 "Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
 "Generated-By: Lingva 5.0.6\n"
holidays/locale/en_US/LC_MESSAGES/PM.po (1)

1-29: Skeleton .po file missing entries
This file currently contains only header metadata without any msgid/msgstr pairs for holiday names. Please populate it with translation entries or placeholders.

holidays/locale/en_US/LC_MESSAGES/WF.po (1)

1-29: Skeleton .po file missing entries
This file currently contains only header metadata without any msgid/msgstr pairs for holiday names. Please populate it with translation entries or placeholders.

holidays/locale/fr/LC_MESSAGES/PM.po (1)

1-29: Skeleton .po file missing entries
This file currently contains only header metadata without any msgid/msgstr pairs for holiday names. Please populate it with translation entries or placeholders.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4291ff3 and fe4486a.

📒 Files selected for processing (14)
  • README.md (4 hunks)
  • holidays/countries/__init__.py (2 hunks)
  • holidays/countries/wallis_and_futuna.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/PM.po (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/WF.po (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/PM.po (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/WF.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/PM.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/WF.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/PM.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/WF.po (1 hunks)
  • holidays/registry.py (2 hunks)
  • snapshots/countries/WF_COMMON.json (1 hunks)
  • tests/countries/test_wallis_and_futuna.py (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:12:57.410Z
Learning: In the France holidays implementation, subdivisions like "GES" and "Metropole" that covered multiple departments with different holiday rules are completely deprecated rather than aliased, because aliasing them to a subset (like Alsace-Moselle) would provide incomplete or incorrect holiday data for the other covered regions. Complete deprecation is preferred over partial/incorrect data coverage.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.159Z
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.
README.md (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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.
🪛 Pylint (3.3.7)
holidays/countries/wallis_and_futuna.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 39-39: Missing class docstring

(C0115)


[convention] 43-43: Missing class docstring

(C0115)


[convention] 47-47: Missing class docstring

(C0115)

tests/countries/test_wallis_and_futuna.py

[convention] 31-31: Line too long (102/100)

(C0301)


[convention] 34-34: Line too long (104/100)

(C0301)


[convention] 37-37: Line too long (101/100)

(C0301)


[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintPierreAndMiquelon.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 33-33: Missing function or method docstring

(C0116)


[convention] 36-36: Missing function or method docstring

(C0116)


[convention] 39-39: Missing function or method docstring

(C0116)


[convention] 58-58: Missing function or method docstring

(C0116)


[convention] 76-76: Missing function or method docstring

(C0116)


[convention] 95-95: Missing function or method docstring

(C0116)


[convention] 114-114: Missing function or method docstring

(C0116)

🪛 Ruff (0.11.9)
tests/countries/test_wallis_and_futuna.py

31-31: Line too long (102 > 99)

(E501)


34-34: Line too long (104 > 99)

(E501)


37-37: Line too long (101 > 99)

(E501)

🪛 GitHub Actions: CI/CD
tests/countries/test_wallis_and_futuna.py

[error] 31-31: Ruff E501: Line too long (102 > 99) in test_feast_of_saint_peter_chanel method.


[error] 34-34: Ruff E501: Line too long (104 > 99) in test_saints_peter_and_paul_day method.


[error] 37-37: Ruff E501: Line too long (101 > 99) in test_territory_day method.

🔇 Additional comments (10)
holidays/countries/__init__.py (2)

165-170: Imports correctly integrated
The SaintPierreAndMiquelon imports (PM, SPM, HolidaysPM) are correctly placed alphabetically between saint_lucia and samoa, aligning with the module definitions.


224-224: Imports correctly integrated
The WallisAndFutuna imports (WF, WLF, HolidaysWF) are correctly placed after vietnam and before yemen, maintaining the existing import ordering.

holidays/registry.py (2)

168-169: Registry entry correctly ordered
The "saint_pierre_and_miquelon" mapping is properly alphabetized between saint_lucia and samoa, with the expected 4-tuple including HolidaysPM.


217-218: Registry entry correctly ordered
The "wallis_and_futuna" mapping is properly alphabetized after vietnam and before yemen, with the correct tuple including HolidaysWF.

snapshots/countries/WF_COMMON.json (1)

1-1222: Snapshot looks good

Dates are in ascending order and naming style matches the existing snapshots in the repo – no blockers spotted.

holidays/countries/wallis_and_futuna.py (1)

34-36: Guard against accidental subdivision override mutations

Because self.subdiv is later used by France._populate_public_holidays() to dispatch
sub-division-specific logic, mutating it in-place is correct.
However, a future refactor in France may read self._orig_subdiv (several core
countries already keep a copy) which would silently break WF.

     def _populate_public_holidays(self) -> None:
-        self.subdiv = "WF"
-        super()._populate_public_holidays()
+        # Force-select WF before delegating to France.
+        orig_subdiv = self.subdiv
+        self.subdiv = "WF"
+        super()._populate_public_holidays()
+        # Restore for safety.
+        self.subdiv = orig_subdiv

Keeps today’s behaviour while future-proofing the override.

⛔ Skipped due to learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/french_southern_territories.py:41-44
Timestamp: 2025-06-18T10:07:58.769Z
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: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:184-206
Timestamp: 2025-06-18T10:58:28.041Z
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.
README.md (4)

584-588: Subdivision list: consider a non-breaking separator

The semicolon separated codes (57 (Moselle), 6AE (Alsace)…) run well past 140 chars
and already wrap on <80 col displays.
A soft-break (<br>) after each comma keeps the table readable without touching the
rendered content.

[ suggest_optional_refactor ]


591-595: Good catch on Thai localisation

th added to both FR and TF rows – keeps README in sync with supported_languages.


1165-1169: Saint-Pierre-et-Miquelon row matches code changes – LGTM

Alias note & language list consistent with new module.


1480-1484: WF row aligned with new country module

All details (alias, languages) are accurate. Nice.

Copy link
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: 2

♻️ Duplicate comments (7)
holidays/locale/th/LC_MESSAGES/MF.po (1)

17-29: Verify translation entries exist.

This file currently contains only header metadata. Confirm that actual msgid/msgstr entries for Saint Martin holidays are present.

holidays/locale/en_US/LC_MESSAGES/MF.po (1)

17-29: Verify translation entries exist.

This file currently contains only header metadata. Confirm that actual msgid/msgstr entries for Saint Martin holidays are present.

holidays/locale/uk/LC_MESSAGES/MF.po (1)

17-29: Verify translation entries exist.

This file currently contains only header metadata. Confirm that actual msgid/msgstr entries for Saint Martin holidays are present.

tests/countries/test_wallis_and_futuna.py (4)

19-19: Fix the class name - copy-paste error from Saint Pierre and Miquelon

The class name TestSaintPierreAndMiquelon doesn't match the country being tested (Wallis and Futuna).


31-32: Fix line length violation

Generator expression exceeds the 99-character limit.


36-37: Fix line length violation

Generator expression exceeds the 99-character limit.


41-42: Fix line length violation

Generator expression exceeds the 99-character limit.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe4486a and ec3d9f9.

📒 Files selected for processing (11)
  • README.md (4 hunks)
  • holidays/countries/__init__.py (2 hunks)
  • holidays/countries/saint_martin.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/MF.po (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/MF.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/MF.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/MF.po (1 hunks)
  • holidays/registry.py (2 hunks)
  • snapshots/countries/MF_COMMON.json (1 hunks)
  • tests/countries/test_saint_martin.py (1 hunks)
  • tests/countries/test_wallis_and_futuna.py (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:12:57.410Z
Learning: In the France holidays implementation, subdivisions like "GES" and "Metropole" that covered multiple departments with different holiday rules are completely deprecated rather than aliased, because aliasing them to a subset (like Alsace-Moselle) would provide incomplete or incorrect holiday data for the other covered regions. Complete deprecation is preferred over partial/incorrect data coverage.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.159Z
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.
holidays/countries/saint_martin.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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.
tests/countries/test_wallis_and_futuna.py (5)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_wallis_and_futuna.py:19-23
Timestamp: 2025-06-18T17:01:58.057Z
Learning: In the vacanza/holidays repository, the standard pattern for test class setUpClass methods is `super().setUpClass(HolidayClass)` or `super().setUpClass(HolidayClass, years=...)` where HolidayClass is passed as the first argument. This is the correct signature that matches the CommonCountryTests.setUpClass method which accepts test_class as the first parameter after cls. Pylint warnings about parameter count mismatch are false positives when comparing against TestCase.setUpClass instead of the immediate parent CommonCountryTests.setUpClass.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.
Learnt from: PPsyrius
PR: vacanza/holidays#2601
File: tests/countries/test_mongolia.py:128-156
Timestamp: 2025-06-15T11:52:39.551Z
Learning: In the vacanza/holidays project tests, when testing holidays that span multiple consecutive days across many years (like Mongolia's National Festival spanning July 11-13), prefer explicit for loops over complex nested generator expressions with unpacking. The explicit loops are more readable, easier to maintain, and better communicate the testing intent even though the Big O complexity is equivalent.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_wallis_and_futuna.py:19-23
Timestamp: 2025-06-18T17:01:58.057Z
Learning: In the vacanza/holidays repository, the standard pattern for test class setUpClass methods is `super().setUpClass(HolidayClass)` where HolidayClass is passed as the first argument. This is the correct signature used across all country test files.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:85-86
Timestamp: 2025-04-05T04:29:38.042Z
Learning: For testing holiday implementations in the vacanza/holidays repository, recommend using `from tests.common import CommonCountryTests` as the base class instead of directly using `unittest.TestCase` to maintain consistency with project conventions and leverage common test utilities.
snapshots/countries/MF_COMMON.json (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2407
File: snapshots/countries/TL_COMMON.json:7-7
Timestamp: 2025-04-03T05:59:57.480Z
Learning: In the holidays project, snapshot files (like snapshots/countries/TL_COMMON.json) are auto-generated when running `make snapshot` and should not be manually edited. Semicolons (;) in holiday entries are used as separators when multiple holidays occur on the same date.
README.md (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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.
🪛 Pylint (3.3.7)
holidays/countries/saint_martin.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 39-39: Missing class docstring

(C0115)


[convention] 43-43: Missing class docstring

(C0115)


[convention] 47-47: Missing class docstring

(C0115)

tests/countries/test_wallis_and_futuna.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintPierreAndMiquelon.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 40-40: Missing function or method docstring

(C0116)


[convention] 45-45: Missing function or method docstring

(C0116)


[convention] 64-64: Missing function or method docstring

(C0116)


[convention] 82-82: Missing function or method docstring

(C0116)


[convention] 101-101: Missing function or method docstring

(C0116)


[convention] 120-120: Missing function or method docstring

(C0116)

tests/countries/test_saint_martin.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintMartin.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 40-40: Missing function or method docstring

(C0116)


[convention] 58-58: Missing function or method docstring

(C0116)


[convention] 75-75: Missing function or method docstring

(C0116)


[convention] 93-93: Missing function or method docstring

(C0116)


[convention] 111-111: Missing function or method docstring

(C0116)

⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Test Python 3.13 on windows-latest
🔇 Additional comments (15)
holidays/locale/fr/LC_MESSAGES/MF.po (1)

15-29: Verify translation entries exist.

This file currently contains only header metadata. Confirm that actual msgid/msgstr entries for Saint Martin holidays are present.

#!/bin/bash
# Count the number of msgid entries beyond the header.
grep -c '^msgid ' holidays/locale/fr/LC_MESSAGES/MF.po
holidays/registry.py (2)

168-169: New registry entries for Saint Martin and Saint Pierre and Miquelon look correct.

The entries are alphabetically placed and include proper ISO codes and class identifiers.


218-218: New registry entry for Wallis and Futuna looks correct.

The entry follows the established pattern with ISO codes and class identifier.

holidays/countries/__init__.py (1)

165-171: LGTM - Clean integration of new territories

The imports follow the established pattern perfectly and maintain alphabetical ordering. The addition of Saint Martin, Saint Pierre and Miquelon, and Wallis and Futuna with their respective aliases is consistent with the existing codebase structure.

Also applies to: 225-225

tests/countries/test_saint_martin.py (3)

19-26: Solid test structure

Clean setup following the common test patterns with proper alias verification.


27-38: Correct historical boundary testing

Good verification that Saint Martin holidays only appear from 2008 onward with regional holidays starting in 2012. This aligns with the historical context of Saint Martin becoming a separate collectivity.


93-109: Excellent Thai localization coverage

The Thai translations look comprehensive and properly test the new localization support mentioned in the PR objectives.

snapshots/countries/MF_COMMON.json (1)

1-551: Auto-generated snapshot data looks consistent

The holiday data properly reflects Saint Martin's timeline with holidays starting from 2008 and region-specific holidays (Abolition of Slavery, Victor Schoelcher Day) appearing from 2012 onward. Data aligns well with the test expectations.

holidays/countries/saint_martin.py (2)

16-32: Well-structured country implementation

Clean subclass design with proper metadata. The start_year of 2008 correctly reflects Saint Martin's separation from Guadeloupe in 2007, and the subdivision overrides follow the established pattern.


34-36: Correct subdivision handling

Setting self.subdiv = "MF" before calling the parent method aligns with the France holiday system's subdivision-based approach. This ensures Saint Martin gets the right holiday set.

README.md (3)

108-108: Accurate country count update

The increase from 191 to 194 countries correctly reflects the addition of Saint Martin, Saint Pierre and Miquelon, and Wallis and Futuna.


586-587: Comprehensive France subdivision update

The updated subdivision list properly reflects the modernized ISO codes and includes all the new territories. The addition of Thai language support is consistent with the PR's localization objectives.


1165-1177: Well-formatted new country entries

The new entries for Saint Martin, Saint Pierre and Miquelon, and Wallis and Futuna follow the established table format perfectly. The note about loading as France subdivisions provides helpful context for users.

Also applies to: 1487-1492

tests/countries/test_wallis_and_futuna.py (2)

45-62: Well-structured comprehensive test

The 2024 holidays test covers all expected holidays with proper French localization. Good validation of the holiday implementation.


64-137: Excellent localization coverage

The localization tests properly validate French (default), English, Thai, and Ukrainian translations. The Thai localization addition aligns with the PR objectives.

Copy link
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

🔭 Outside diff range comments (4)
holidays/locale/th/LC_MESSAGES/MQ.po (1)

1-29: Stub Thai localization file added
The PO file correctly sets up metadata for the th locale but contains no msgid/msgstr entries yet. Please populate the actual holiday translation strings in a follow-up.

holidays/locale/uk/LC_MESSAGES/MQ.po (1)

1-29: Stub Ukrainian localization file added
Headers and locale settings are correct, but no msgid/msgstr pairs are present. Don’t forget to add the actual holiday translations for Martinique in Ukrainian.

holidays/locale/en_US/LC_MESSAGES/MQ.po (1)

1-29: Stub English (en_US) localization file added
The file header aligns with other en_US PO files, but it lacks any msgid entries for the holiday labels. Populate this template with the English holiday names or merge with the pot file.

holidays/locale/fr/LC_MESSAGES/MQ.po (1)

1-29: Stub French localization file added
The PO header is in line with the project standard, yet no translations are included. Add the French holiday strings for Martinique in a subsequent update.

♻️ Duplicate comments (1)
tests/countries/test_wallis_and_futuna.py (1)

19-138: Solid test structure with minor formatting issues.

The test suite provides comprehensive coverage of Wallis and Futuna holidays including territory-specific holidays and multi-language localization. The class naming appears correctly set to TestWallisAndFutuna now.

However, there are line length violations in the generator expressions that should be addressed for consistency with project standards.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 704e817 and 5e27fbb.

📒 Files selected for processing (15)
  • README.md (6 hunks)
  • holidays/countries/__init__.py (3 hunks)
  • holidays/countries/martinique.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/MQ.po (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/MQ.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/MQ.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/MQ.po (1 hunks)
  • holidays/registry.py (3 hunks)
  • snapshots/countries/MQ_COMMON.json (1 hunks)
  • tests/countries/test_french_southern_territories.py (1 hunks)
  • tests/countries/test_martinique.py (1 hunks)
  • tests/countries/test_saint_barthelemy.py (1 hunks)
  • tests/countries/test_saint_martin.py (1 hunks)
  • tests/countries/test_saint_pierre_and_miquelon.py (1 hunks)
  • tests/countries/test_wallis_and_futuna.py (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:12:57.410Z
Learning: In the France holidays implementation, subdivisions like "GES" and "Metropole" that covered multiple departments with different holiday rules are completely deprecated rather than aliased, because aliasing them to a subset (like Alsace-Moselle) would provide incomplete or incorrect holiday data for the other covered regions. Complete deprecation is preferred over partial/incorrect data coverage.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-180
Timestamp: 2025-06-18T10:26:50.159Z
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.
holidays/locale/en_US/LC_MESSAGES/MQ.po (1)
Learnt from: KJhellico
PR: vacanza/holidays#2388
File: holidays/locale/en_CI/LC_MESSAGES/CI.po:88-88
Timestamp: 2025-03-30T18:25:07.087Z
Learning: In the holidays library, localization files have a specific structure: message comments are in standard English (en_US) describing the holiday, while actual translations (msgstr) should use the locale-specific terminology (e.g., en_CI for Ivory Coast English). For example, "Night of Power" in standard English is translated as "Lailatou-Kadr" in Ivory Coast English.
README.md (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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.
tests/countries/test_wallis_and_futuna.py (4)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_wallis_and_futuna.py:19-23
Timestamp: 2025-06-18T17:01:58.057Z
Learning: In the vacanza/holidays repository, the standard pattern for test class setUpClass methods is `super().setUpClass(HolidayClass)` or `super().setUpClass(HolidayClass, years=...)` where HolidayClass is passed as the first argument. This is the correct signature that matches the CommonCountryTests.setUpClass method which accepts test_class as the first parameter after cls. Pylint warnings about parameter count mismatch are false positives when comparing against TestCase.setUpClass instead of the immediate parent CommonCountryTests.setUpClass.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_wallis_and_futuna.py:19-23
Timestamp: 2025-06-18T17:01:58.057Z
Learning: In the vacanza/holidays repository, the standard pattern for test class setUpClass methods is `super().setUpClass(HolidayClass)` where HolidayClass is passed as the first argument. This is the correct signature used across all country test files.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:85-86
Timestamp: 2025-04-05T04:29:38.042Z
Learning: For testing holiday implementations in the vacanza/holidays repository, recommend using `from tests.common import CommonCountryTests` as the base class instead of directly using `unittest.TestCase` to maintain consistency with project conventions and leverage common test utilities.
tests/countries/test_french_southern_territories.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.
🪛 Pylint (3.3.7)
tests/countries/test_saint_martin.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintMartin.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 40-40: Missing function or method docstring

(C0116)


[convention] 58-58: Missing function or method docstring

(C0116)


[convention] 75-75: Missing function or method docstring

(C0116)


[convention] 93-93: Missing function or method docstring

(C0116)


[convention] 111-111: Missing function or method docstring

(C0116)

tests/countries/test_saint_pierre_and_miquelon.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 24-24: Missing class docstring

(C0115)


[warning] 26-26: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintPierreAndMiquelon.setUpClass' method

(W0221)


[convention] 29-29: Missing function or method docstring

(C0116)


[convention] 32-32: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 51-51: Missing function or method docstring

(C0116)


[convention] 66-66: Missing function or method docstring

(C0116)


[convention] 82-82: Missing function or method docstring

(C0116)


[convention] 98-98: Missing function or method docstring

(C0116)

tests/countries/test_martinique.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestMartinique.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 44-44: Missing function or method docstring

(C0116)


[convention] 49-49: Missing function or method docstring

(C0116)


[convention] 54-54: Missing function or method docstring

(C0116)


[convention] 73-73: Missing function or method docstring

(C0116)


[convention] 91-91: Missing function or method docstring

(C0116)


[convention] 110-110: Missing function or method docstring

(C0116)


[convention] 129-129: Missing function or method docstring

(C0116)

holidays/countries/martinique.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 39-39: Missing class docstring

(C0115)


[convention] 43-43: Missing class docstring

(C0115)


[convention] 47-47: Missing class docstring

(C0115)

tests/countries/test_saint_barthelemy.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintBarthelemy.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 52-52: Missing function or method docstring

(C0116)


[convention] 68-68: Missing function or method docstring

(C0116)


[convention] 85-85: Missing function or method docstring

(C0116)


[convention] 102-102: Missing function or method docstring

(C0116)

tests/countries/test_wallis_and_futuna.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestWallisAndFutuna.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 40-40: Missing function or method docstring

(C0116)


[convention] 45-45: Missing function or method docstring

(C0116)


[convention] 64-64: Missing function or method docstring

(C0116)


[convention] 82-82: Missing function or method docstring

(C0116)


[convention] 101-101: Missing function or method docstring

(C0116)


[convention] 120-120: Missing function or method docstring

(C0116)

tests/countries/test_french_southern_territories.py

[convention] 24-24: Missing class docstring

(C0115)


[warning] 26-26: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestFrenchSouthernTerritories.setUpClass' method

(W0221)


[convention] 29-29: Missing function or method docstring

(C0116)


[convention] 32-32: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 51-51: Missing function or method docstring

(C0116)


[convention] 66-66: Missing function or method docstring

(C0116)


[convention] 82-82: Missing function or method docstring

(C0116)


[convention] 98-98: Missing function or method docstring

(C0116)

⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Build distribution
🔇 Additional comments (19)
holidays/registry.py (5)

133-133: Add Martinique to registry
Entry for "martinique" uses the correct class name and ISO codes (MQ, MTQ, HolidaysMQ) and is in alphabetical order.


167-167: Add Saint Barthélemy to registry
"saint_barthelemy": ("SaintBarthelemy", "BL", "BLM", "HolidaysBL") correctly reflects the class and ISO codes, and its position is sorted.


170-170: Add Saint Martin to registry
"saint_martin": ("SaintMartin", "MF", "MAF", "HolidaysMF") is accurate—ISO-2 MF and ISO-3 MAF.


171-171: Add Saint Pierre and Miquelon to registry
("SaintPierreAndMiquelon", "PM", "SPM", "HolidaysPM") matches the module, and the entry is alphabetically placed.


220-220: Add Wallis and Futuna to registry
"wallis_and_futuna": ("WallisAndFutuna", "WF", "WLF", "HolidaysWF") is consistent with naming conventions and sorted correctly.

holidays/countries/__init__.py (1)

130-130: LGTM! Clean integration of new French territory modules.

The import statements follow the established pattern perfectly and maintain alphabetical ordering. Good work on consistent naming conventions across all the new territory modules.

Also applies to: 164-164, 167-173, 227-227

tests/countries/test_saint_pierre_and_miquelon.py (2)

24-33: Solid test foundation with proper boundary validation.

The alias testing and start year validation (1815) correctly reflects Saint Pierre and Miquelon's historical transition from UK control. Good defensive testing approach.


51-112: Excellent localization coverage across four languages.

The comprehensive testing of French, English, Thai, and Ukrainian translations demonstrates thorough internationalization support. The Thai localization addition aligns well with the PR's stated goals.

tests/countries/test_saint_martin.py (2)

30-38: Good historical accuracy in holiday date validation.

The specific testing of "Abolition de l'esclavage" and "Fête de Victor Schoelcher" starting in 2012 shows attention to historical detail. The year range validation ensures data integrity.


93-127: Strong multilingual support implementation.

The Thai localization with proper Unicode characters and comprehensive language coverage demonstrates robust internationalization. Well-executed testing across all supported locales.

tests/countries/test_martinique.py (2)

30-52: Comprehensive holiday validation with proper historical dating.

The testing of Good Friday (from 1803), Abolition of Slavery (from 1984), and Victor Schoelcher Day (from 1984) demonstrates solid historical research and proper boundary testing for holiday enactment dates.


110-146: Robust multilingual testing with accurate translations.

The localization tests cover all supported languages with proper character encoding for Thai and Ukrainian scripts. The translation quality appears consistent across all locales.

snapshots/countries/MQ_COMMON.json (1)

1-1315: Well-structured holiday snapshot with accurate historical progression.

The JSON data correctly reflects holiday evolution, particularly the introduction of "Abolition of Slavery" and "Victor Schoelcher Day" starting in 1984. The comprehensive 100-year span provides excellent test coverage and the format is clean and consistent.

README.md (3)

108-108: Accurate country count update.

The increase from 191 to 196 correctly reflects the addition of 5 new French territories as separate country entities.


586-587: Comprehensive subdivision documentation with Thai localization.

The expanded subdivision listing properly documents all French territories with their codes, and the Thai language addition supports the new internationalization effort.


920-925: Well-documented new French territory entries.

All five new territory entries follow consistent formatting with correct ISO codes, proper subdivision references, and comprehensive language support including the new Thai localization.

Also applies to: 1158-1163, 1179-1184, 1186-1191, 1501-1506

holidays/countries/martinique.py (1)

16-36: Solid implementation pattern for French territory.

The subclassing approach, subdivision assignment to "972", and alias structure follow the correct patterns for French overseas territories. The 1803 start year aligns with historical context.

Also applies to: 39-48

tests/countries/test_saint_barthelemy.py (1)

19-118: Comprehensive test coverage for Saint Barthélemy.

The test suite thoroughly validates holiday aliases, historical boundaries (no holidays before 2008), specific territory holidays like "Abolition de l'esclavage" from 2012, and multi-language localization. Well-structured following project conventions.

tests/countries/test_french_southern_territories.py (1)

24-112: Enhanced test coverage with proper localization validation.

The improvements include better class naming, expanded year coverage, and comprehensive localization tests for French, English, Thai, and Ukrainian. The date/name tuple validation approach is more robust than previous date-only checks.

Copy link
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: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e27fbb and 3508cde.

📒 Files selected for processing (15)
  • README.md (7 hunks)
  • holidays/countries/__init__.py (4 hunks)
  • holidays/countries/guadeloupe.py (1 hunks)
  • holidays/countries/martinique.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/GP.po (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/GP.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/GP.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/GP.po (1 hunks)
  • holidays/registry.py (4 hunks)
  • snapshots/countries/GP_COMMON.json (1 hunks)
  • tests/countries/test_guadeloupe.py (1 hunks)
  • tests/countries/test_martinique.py (1 hunks)
  • tests/countries/test_saint_barthelemy.py (1 hunks)
  • tests/countries/test_saint_martin.py (1 hunks)
  • tests/countries/test_wallis_and_futuna.py (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
holidays/locale/fr/LC_MESSAGES/GP.po (1)
Learnt from: KJhellico
PR: vacanza/holidays#2398
File: holidays/locale/fr/LC_MESSAGES/GN.po:31-83
Timestamp: 2025-03-31T20:25:12.808Z
Learning: In the holidays library, French (fr) is the default language for Guinea. This means that message IDs (msgid) in the PO files are already in French, and message strings (msgstr) in the French locale files can remain empty, as no translation is needed.
README.md (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: holidays/countries/france.py:178-182
Timestamp: 2025-06-18T10:18:59.409Z
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.
snapshots/countries/GP_COMMON.json (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2407
File: snapshots/countries/TL_COMMON.json:7-7
Timestamp: 2025-04-03T05:59:57.480Z
Learning: In the holidays project, snapshot files (like snapshots/countries/TL_COMMON.json) are auto-generated when running `make snapshot` and should not be manually edited. Semicolons (;) in holiday entries are used as separators when multiple holidays occur on the same date.
tests/countries/test_wallis_and_futuna.py (5)
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_wallis_and_futuna.py:19-23
Timestamp: 2025-06-18T17:01:58.057Z
Learning: In the vacanza/holidays repository, the standard pattern for test class setUpClass methods is `super().setUpClass(HolidayClass)` or `super().setUpClass(HolidayClass, years=...)` where HolidayClass is passed as the first argument. This is the correct signature that matches the CommonCountryTests.setUpClass method which accepts test_class as the first parameter after cls. Pylint warnings about parameter count mismatch are false positives when comparing against TestCase.setUpClass instead of the immediate parent CommonCountryTests.setUpClass.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.
Learnt from: PPsyrius
PR: vacanza/holidays#2601
File: tests/countries/test_mongolia.py:128-156
Timestamp: 2025-06-15T11:52:39.551Z
Learning: In the vacanza/holidays project tests, when testing holidays that span multiple consecutive days across many years (like Mongolia's National Festival spanning July 11-13), prefer explicit for loops over complex nested generator expressions with unpacking. The explicit loops are more readable, easier to maintain, and better communicate the testing intent even though the Big O complexity is equivalent.
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_wallis_and_futuna.py:19-23
Timestamp: 2025-06-18T17:01:58.057Z
Learning: In the vacanza/holidays repository, the standard pattern for test class setUpClass methods is `super().setUpClass(HolidayClass)` where HolidayClass is passed as the first argument. This is the correct signature used across all country test files.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:85-86
Timestamp: 2025-04-05T04:29:38.042Z
Learning: For testing holiday implementations in the vacanza/holidays repository, recommend using `from tests.common import CommonCountryTests` as the base class instead of directly using `unittest.TestCase` to maintain consistency with project conventions and leverage common test utilities.
🪛 Pylint (3.3.7)
tests/countries/test_saint_martin.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintMartin.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 40-40: Missing function or method docstring

(C0116)


[convention] 58-58: Missing function or method docstring

(C0116)


[convention] 75-75: Missing function or method docstring

(C0116)


[convention] 93-93: Missing function or method docstring

(C0116)


[convention] 111-111: Missing function or method docstring

(C0116)

holidays/countries/guadeloupe.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 39-39: Missing class docstring

(C0115)


[convention] 43-43: Missing class docstring

(C0115)


[convention] 47-47: Missing class docstring

(C0115)

tests/countries/test_martinique.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestMartinique.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 44-44: Missing function or method docstring

(C0116)


[convention] 49-49: Missing function or method docstring

(C0116)


[convention] 54-54: Missing function or method docstring

(C0116)


[convention] 73-73: Missing function or method docstring

(C0116)


[convention] 91-91: Missing function or method docstring

(C0116)


[convention] 110-110: Missing function or method docstring

(C0116)


[convention] 129-129: Missing function or method docstring

(C0116)

holidays/countries/martinique.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 39-39: Missing class docstring

(C0115)


[convention] 43-43: Missing class docstring

(C0115)


[convention] 47-47: Missing class docstring

(C0115)

tests/countries/test_guadeloupe.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestMartinique.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 44-44: Missing function or method docstring

(C0116)


[convention] 58-58: Missing function or method docstring

(C0116)


[convention] 63-63: Missing function or method docstring

(C0116)


[convention] 68-68: Missing function or method docstring

(C0116)


[convention] 88-88: Missing function or method docstring

(C0116)


[convention] 107-107: Missing function or method docstring

(C0116)


[convention] 127-127: Missing function or method docstring

(C0116)


[convention] 147-147: Missing function or method docstring

(C0116)

tests/countries/test_wallis_and_futuna.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestWallisAndFutuna.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 40-40: Missing function or method docstring

(C0116)


[convention] 45-45: Missing function or method docstring

(C0116)


[convention] 64-64: Missing function or method docstring

(C0116)


[convention] 82-82: Missing function or method docstring

(C0116)


[convention] 101-101: Missing function or method docstring

(C0116)


[convention] 120-120: Missing function or method docstring

(C0116)

tests/countries/test_saint_barthelemy.py

[convention] 1-1: Missing module docstring

(C0114)


[convention] 19-19: Missing class docstring

(C0115)


[warning] 21-21: Number of parameters was 4 in 'TestCase.setUpClass' and is now 1 in overriding 'TestSaintBarthelemy.setUpClass' method

(W0221)


[convention] 24-24: Missing function or method docstring

(C0116)


[convention] 27-27: Missing function or method docstring

(C0116)


[convention] 30-30: Missing function or method docstring

(C0116)


[convention] 35-35: Missing function or method docstring

(C0116)


[convention] 52-52: Missing function or method docstring

(C0116)


[convention] 68-68: Missing function or method docstring

(C0116)


[convention] 85-85: Missing function or method docstring

(C0116)


[convention] 102-102: Missing function or method docstring

(C0116)

⏰ Context from checks skipped due to timeout of 300000ms (1)
  • GitHub Check: Test Python 3.13 on windows-latest
🔇 Additional comments (16)
holidays/locale/fr/LC_MESSAGES/GP.po (1)

1-29: LGTM! Proper French localization structure.

The file follows the correct PO format and metadata structure. Based on the retrieved learning, leaving msgstr empty is appropriate since French is the default language for French territories - no translation needed from French to French.

holidays/locale/th/LC_MESSAGES/GP.po (1)

1-29: LGTM! Thai localization template properly structured.

The file correctly establishes the Thai localization framework with appropriate headers and language configuration. Ready for future translation additions.

holidays/locale/en_US/LC_MESSAGES/GP.po (1)

1-29: LGTM! English localization follows standard structure.

The file maintains consistency with other localization files in the project, with proper headers and language configuration for English US translations.

holidays/locale/uk/LC_MESSAGES/GP.po (1)

1-29: LGTM! Ukrainian localization maintains project consistency.

The file structure aligns with project standards and properly configures Ukrainian language support for Guadeloupe holidays.

holidays/registry.py (4)

95-95: LGTM! Guadeloupe entry properly added.

The entry follows the correct format and maintains alphabetical ordering in the registry.


134-134: LGTM! Martinique entry correctly positioned.

The entry maintains proper alphabetical order and follows standard naming conventions.


168-172: LGTM! Saint territories properly added.

All three Saint territories (Barthélemy, Martin, Pierre and Miquelon) are correctly positioned alphabetically and follow consistent naming patterns.


221-221: LGTM! Wallis and Futuna completes the additions.

The final territory entry maintains proper alphabetical placement and consistent formatting.

holidays/countries/__init__.py (1)

91-91: Import additions look good.

These new imports for French overseas territories follow the established pattern and maintain alphabetical ordering.

Also applies to: 131-131, 165-165, 168-174, 228-228

tests/countries/test_saint_martin.py (1)

19-127: Test implementation follows established patterns correctly.

The test structure, holiday validations, and localization checks are consistent with other country test modules in the codebase.

snapshots/countries/GP_COMMON.json (1)

1-1415: Snapshot file is auto-generated.

This holiday data snapshot is auto-generated when running make snapshot and should not be manually edited. The format looks consistent with other snapshot files in the project.

tests/countries/test_martinique.py (1)

1-147: Well-structured test implementation

The test module follows established patterns and provides comprehensive coverage for Martinique holidays including aliases, date ranges, specific holidays, and multi-language localization. The structure aligns perfectly with other country test files in the codebase.

README.md (1)

108-1513: Documentation accurately reflects the expanded French territories support

The README updates correctly capture the addition of 6 new country codes (bringing total from 191 to 197) and properly documents the new French overseas territories with their subdivision codes and Thai localization support. The documentation is consistent and well-organized.

holidays/countries/martinique.py (1)

16-48: Correct implementation for Martinique holidays

The holiday provider properly inherits from France with the correct country code "MQ", subdivision "972", and historically accurate start year of 1803. The implementation follows established patterns for French overseas territories.

tests/countries/test_saint_barthelemy.py (1)

1-118: Comprehensive test coverage for Saint Barthélemy

The test module provides thorough coverage including proper historical boundaries (start year 2008, Abolition de l'esclavage from 2012) and multi-language localization. The structure matches established testing patterns in the codebase.

tests/countries/test_wallis_and_futuna.py (1)

19-43: Test structure follows established patterns correctly

The class name and setUpClass implementation are correct. The pylint warning about parameter mismatch is a false positive - this signature matches the CommonCountryTests.setUpClass method as used throughout the codebase. The test coverage for territory-specific holidays is appropriate.

Copy link
Collaborator

@KJhellico KJhellico left a comment

Choose a reason for hiding this comment

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

It's powerful! 🚀

Co-authored-by: ~Jhellico <KJhellico@users.noreply.github.com>
Signed-off-by: Panpakorn Siripanich <19505219+PPsyrius@users.noreply.github.com>
@sonarqubecloud
Copy link

Copy link
Collaborator

@KJhellico KJhellico left a comment

Choose a reason for hiding this comment

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

LGTM! 🚀

Copy link
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.

This is 200+ supported entities PR -- awesome work @PPsyrius!

LGTM 🚀

@arkid15r arkid15r added this pull request to the merge queue Jun 19, 2025
Merged via the queue into vacanza:dev with commit 0b5ba28 Jun 19, 2025
33 checks passed
@PPsyrius PPsyrius deleted the FR_refactor branch June 20, 2025 02:55
This was referenced Jul 4, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jul 9, 2025
9 tasks
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.

Add Wallis and Futuna holidays Add Mayotte holidays Add Saint Barthélemy holidays

3 participants