+
Skip to content

Conversation

Roshan-1024
Copy link
Contributor

Proposed change

Add Togo holidays.

Resolves #1287.

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

Copy link
Contributor

coderabbitai bot commented May 4, 2025

Summary by CodeRabbit

  • New Features

    • Added support for Togo's holiday calendar, including public and workday holidays, with accurate historical and religious observances.
    • Introduced French and English language support for Togo holidays, with French as the default.
    • Included aliases for Togo using country codes TG and TGO.
  • Documentation

    • Updated documentation to reflect Togo as a supported country.
  • Tests

    • Added comprehensive tests to ensure the accuracy and localization of Togo's holiday calendar.

Summary by CodeRabbit

  • New Features
    • Added support for Togo's public and optional holidays, including Christian, International, and Islamic observances, with accurate historical and religious holiday coverage.
    • Introduced localization for Togo holidays in both English and French.
  • Documentation
    • Updated documentation to reflect Togo as a supported country, now totaling 175 supported countries.
  • Tests
    • Added comprehensive tests to ensure correct holiday calculations and localization for Togo.

Walkthrough

This update introduces support for Togo's public and optional holidays in the holidays library. It adds a new Togo holiday calendar implementation, corresponding French and English translations, registry entries, and a comprehensive test suite. The README and country registry are updated to reflect Togo's inclusion. The test module ensures accurate holiday logic, including fixed, movable, optional, historical, and religious observances.

Changes

Files/Paths Change Summary
README.md, holidays/registry.py Added Togo to supported country list and registry, updated documentation for 175 countries.
holidays/countries/togo.py Added Togo holiday calendar implementation, including aliases (TG, TGO) and custom Islamic holiday logic.
holidays/locale/fr/LC_MESSAGES/TG.po Introduced French translation file for Togo holiday names and observance notes.
holidays/locale/en_US/LC_MESSAGES/TG.po Added English translations for Togo holiday names.
holidays/countries/init.py Imported Togo classes (Togo, TG, TGO) into country package.
tests/countries/test_togo.py Created comprehensive test suite for Togo holidays, covering fixed, movable, optional, and historical holidays.

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Add Togo holidays (#1287)

Possibly related PRs

Suggested reviewers

  • KJhellico
  • PPsyrius
  • arkid15r

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 24de3e0 and 6f109d2.

📒 Files selected for processing (2)
  • holidays/countries/togo.py (1 hunks)
  • tests/countries/test_togo.py (1 hunks)
⏰ Context from checks skipped due to timeout of 300000ms (2)
  • GitHub Check: Test build on ubuntu-latest
  • GitHub Check: Test build on windows-latest
🔇 Additional comments (16)
holidays/countries/togo.py (9)

1-20: Clean, well-structured imports and setup.

The file follows the project's established pattern for holiday definitions with appropriate imports. Good job including all necessary holiday components.


22-48: Well-documented with comprehensive references.

Excellent job providing archived links for your references - this ensures long-term stability for documentation. The dedicated section for Ramadan start dates with yearly references is particularly thorough.


59-71: Well-structured initialization with proper parameter documentation.

The custom Islamic calendar initialization is properly documented with clear parameter explanations.


73-116: Comprehensive public holidays implementation.

Good job implementing all required holidays with proper translations. The holiday definitions correctly use the tr() function for internationalization support.


117-121: Clean workday holiday implementation.

The workday holiday is correctly implemented with appropriate historical constraints.


123-128: Standard country code aliases.

The aliases follow the project's convention.


150-168: Good historical coverage for Eid al-Fitr dates.

The date mappings provide comprehensive coverage from 2010-2025 with consistent year-by-year progression.


170-182: Appropriate Ramadan date coverage.

While Ramadan dates only go back to 2015 (compared to 2010 for other holidays), this appears to be an intentional choice based on data availability as referenced in the PR comments.


50-57:

✅ Verification successful

Potential discrepancy between independence date and start year.

There's a comment noting Togo's independence on April 27, 1960, but start_year is set to 1961. Consider whether holidays should be supported from 1960 onwards.

Run this script to check how other countries handle their independence year vs. start year:


🏁 Script executed:

#!/bin/bash
# Check other country implementations for similar patterns regarding independence year vs start_year
grep -A 2 "independence" --include="*.py" holidays/countries/ | grep -B 2 -A 2 "start_year"

Length of output: 131


Let’s rerun the search recursively to catch all instances of independence comments vs. start_year settings:


🏁 Script executed:

#!/bin/bash
echo "== Independence comments =="
grep -R -i -n --include="*.py" "independence" holidays/countries/

echo
echo "== start_year definitions =="
grep -R -n --include="*.py" "start_year" holidays/countries/

Length of output: 25245


No change needed: start_year aligns with the established pattern
The library consistently sets start_year to the year after independence for countries whose independence fell later in the year (e.g. Burkina Faso, Chad, Sierra Leone), reserving the same-year rule only for January 1 independences (Cameroon). Togo’s April 27, 1960 independence therefore correctly uses start_year = 1961.

tests/countries/test_togo.py (7)

1-27: Well-structured test setup.

The test class properly inherits from CommonCountryTests and sets up necessary test fixtures. Good approach creating a separate instance for non-estimated holidays testing.


28-34: Proper validation for country codes and pre-independence.

The tests correctly verify country code aliases and absence of holidays before independence.


35-101: Thorough testing of standard holidays.

The tests comprehensively verify all fixed and movable Christian holidays with appropriate date ranges and specific year examples.


102-140: Comprehensive Islamic holiday testing.

Good job testing Islamic holidays with both estimated and non-estimated variants. The specific date assertions match the custom date mappings defined in the implementation.


141-148: Complete workday holiday testing.

The anniversary test correctly verifies availability only from 1987 onward and in the appropriate category.


149-183: Well-structured year-specific tests.

The 2024 and 2025 test cases provide a comprehensive validation of the entire holiday set with correct chronological ordering.


185-220: Complete localization testing.

The tests properly validate translations in both French (default) and English locales. All holiday names are verified in both languages.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch TG
  • 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 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.

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 180b104 and 3595f4a.

📒 Files selected for processing (5)
  • README.md (2 hunks)
  • holidays/countries/togo.py (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/TG.po (1 hunks)
  • holidays/registry.py (1 hunks)
  • tests/countries/test_togo.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
holidays/locale/fr/LC_MESSAGES/TG.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.
🧬 Code Graph Analysis (1)
tests/countries/test_togo.py (2)
tests/common.py (7)
  • TestCase (28-338)
  • CommonCountryTests (356-374)
  • assertAliases (121-130)
  • assertNoHolidays (292-294)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
  • assertHolidays (228-230)
holidays/countries/togo.py (3)
  • Togo (26-137)
  • TG (140-141)
  • TGO (144-145)
🔇 Additional comments (12)
holidays/registry.py (1)

175-175: Togo entry successfully added

The Togo entry is correctly positioned alphabetically in the COUNTRIES registry with proper ISO codes.

README.md (2)

108-108: Total country count updated correctly

The number of supported countries is correctly incremented from 171 to 172 to reflect Togo's addition.


1215-1220: Togo documentation entry correctly added

The Togo entry is properly added to the countries table with appropriate ISO code, language support, and holiday category information.

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

1-94: French translations for Togo properly implemented

This new translation file correctly provides French holiday names for Togo. Since French is the default language for Togo, the message strings (msgstr) are appropriately left empty as no translation is needed from the message IDs that are already in French.

The file includes all necessary holiday name definitions, including fixed date holidays, Christian observances, Islamic holidays, and format strings for estimated and observed holidays.

tests/countries/test_togo.py (6)

13-27: Test setup is comprehensive

The test class is properly set up with appropriate imports, year ranges (1960-2050), and test variations including holidays with and without estimated labels and optional holidays.


28-34: Country aliases and pre-independence tests are correct

Tests appropriately verify:

  1. The country aliases (TG, TGO) for Togo
  2. No holidays exist before independence (1959)

This ensures proper historical accuracy and code organization.


35-112: Fixed and Christian holidays tests are thorough

The tests comprehensively cover:

  1. Fixed date holidays (New Year's Day, Independence Day, Labor Day, etc.)
  2. Christian movable holidays (Good Friday, Easter Monday, Ascension, etc.)
  3. Historical holidays (Liberation Day from 1967-2013)

All date calculations and ranges are accurate.


113-176: Islamic holidays tests include known dates

The tests for Islamic holidays (Ramadan, Eid al-Fitr, and Eid al-Adha) include concrete test cases with known dates for multiple years, ensuring the lunar calendar calculations are accurate. Tests also verify behavior with and without estimated labels.


177-202: Optional holidays tests are properly implemented

Tests for optional holidays like Mawlid and the Anniversary of the Failed Attack on Lomé correctly:

  1. Filter by the OPTIONAL category
  2. Include known dates for verification
  3. Check historical boundaries (post-1987 for the Anniversary)

203-240: Comprehensive year tests validate holiday combinations

The full year tests for 2024 and 2025 verify that all holidays appear correctly together, ensuring the overall holiday set is accurate and complete for these sample years.

holidays/countries/togo.py (2)

148-208: Limited date range for Islamic holidays

The Islamic holiday dates are only defined up to 2025. Consider adding a comment indicating when these dates should be reviewed and updated to ensure long-term maintenance.

class TogoIslamicHolidays(_CustomIslamicHolidays):
+    # These dates should be reviewed and extended beyond 2025 before that year

1-209: Solid implementation of Togo holiday calendar

The implementation follows the library patterns well, with comprehensive documentation, proper references for holiday sources, and good organization of public and optional holidays. The date handling is thorough, especially for Islamic holidays which follow a lunar calendar.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3595f4a and 55b077c.

📒 Files selected for processing (3)
  • README.md (2 hunks)
  • holidays/countries/togo.py (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/TG.po (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
holidays/countries/togo.py (5)
holidays/calendars/islamic.py (1)
  • _CustomIslamicHolidays (3881-3882)
holidays/groups/christian.py (7)
  • ChristianHolidays (22-463)
  • _add_good_friday (308-317)
  • _add_easter_monday (259-268)
  • _add_ascension_thursday (119-127)
  • _add_whit_monday (432-441)
  • _add_all_saints_day (97-105)
  • _add_christmas_day (208-216)
holidays/groups/international.py (2)
  • InternationalHolidays (18-220)
  • _add_new_years_day (126-134)
holidays/groups/islamic.py (5)
  • IslamicHolidays (20-426)
  • _add_ramadan_beginning_day (386-396)
  • _add_eid_al_fitr_day (152-163)
  • _add_eid_al_adha_day (109-120)
  • _add_mawlid_day (329-339)
holidays/observed_holiday_base.py (1)
  • ObservedHolidayBase (101-243)
🔇 Additional comments (9)
README.md (2)

108-108: Update supported country count
The total country count was correctly incremented from 171 to 172 to account for Togo.


1215-1220: Togo entry matches implementation
The new table row for Togo (TG) with French language support and OPTIONAL category aligns with the Togo class (default_language="fr" and supported_categories includes OPTIONAL).

holidays/locale/fr/LC_MESSAGES/TG.po (2)

1-15: Header metadata looks good
The file header correctly identifies the project, authors, and license.


16-98: Populate msgstr for French translations
The .po file currently contains empty msgstr "" for all entries. To make the French locale functional, each msgstr should either mirror the msgid (for untranslated defaults) or provide the proper French translation. Consider running msgmerge or copying the msgid into msgstr as a first pass.

holidays/countries/togo.py (5)

13-23: Imports are correct and complete
Required modules (gettext, calendar constants, holiday groups, and base classes) are appropriately imported.


84-130: Holiday additions look sound
Public holidays (fixed and movable) are correctly added with translation wrappers and accurate year conditions (e.g., Liberation Day only 1967–2013).


131-138: Optional holiday logic is correct
Mawlid is always included and the failed-attack anniversary starts in 1987. Conditions and method calls match requirements.


140-146: Aliases for TG and TGO are in place
Providing both TG and TGO aliases aligns with ISO code conventions.


148-209: Custom Islamic dates mapping is thorough
Explicit date mappings for Eid al-Adha, Eid al-Fitr, Mawlid, and Ramadan covering 2010–2025 are provided. Consider verifying that fallback lunar calculations align correctly for years prior to the first mapped entry.

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

♻️ Duplicate comments (1)
holidays/countries/togo.py (1)

59-59: 🧹 Nitpick (assertive)

Remove redundant PUBLIC from supported_categories
PUBLIC is the default category inherited from HolidayBase. You can simplify to only list non-default categories:

-    supported_categories = (OPTIONAL, PUBLIC)
+    supported_categories = (OPTIONAL,)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 55b077c and 2e5004e.

📒 Files selected for processing (2)
  • holidays/countries/togo.py (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/TG.po (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
holidays/locale/fr/LC_MESSAGES/TG.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.
holidays/countries/togo.py (1)
Learnt from: KJhellico
PR: vacanza/holidays#2437
File: holidays/countries/bhutan.py:27-30
Timestamp: 2025-04-08T14:46:10.656Z
Learning: For country classes in the holidays library, there's no need to explicitly specify `supported_categories = (PUBLIC,)` when PUBLIC is the only category being used, as it's already the default category inherited from HolidayBase.
🧬 Code Graph Analysis (1)
holidays/countries/togo.py (5)
holidays/calendars/islamic.py (1)
  • _CustomIslamicHolidays (3881-3882)
holidays/groups/christian.py (7)
  • ChristianHolidays (22-463)
  • _add_good_friday (308-317)
  • _add_easter_monday (259-268)
  • _add_ascension_thursday (119-127)
  • _add_whit_monday (432-441)
  • _add_all_saints_day (97-105)
  • _add_christmas_day (208-216)
holidays/groups/international.py (2)
  • InternationalHolidays (18-220)
  • _add_new_years_day (126-134)
holidays/groups/islamic.py (5)
  • IslamicHolidays (20-426)
  • _add_ramadan_beginning_day (386-396)
  • _add_eid_al_fitr_day (152-163)
  • _add_eid_al_adha_day (109-120)
  • _add_mawlid_day (329-339)
holidays/holiday_base.py (1)
  • HolidayBase (57-1301)
🔇 Additional comments (2)
holidays/locale/fr/LC_MESSAGES/TG.po (1)

13-14: French locale header is correctly set up
French is the default language, so having msgid entries in French with empty msgstr is appropriate.

holidays/countries/togo.py (1)

84-87: Verify Liberation Day date range boundaries
The condition if 1967 <= year < 2014 excludes 2014. Confirm whether Liberation Day should be observed in 2014 or end in 2013.

Do your tests cover the year 2014 case? If the holiday runs through 2014, consider changing to self._year <= 2014.

Copy link

codecov bot commented May 4, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (6feaf40) to head (6f109d2).
Report is 1 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff            @@
##               dev     #2525   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          218       219    +1     
  Lines        13910     13956   +46     
  Branches      1954      1956    +2     
=========================================
+ Hits         13910     13956   +46     

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

♻️ Duplicate comments (6)
holidays/locale/fr/LC_MESSAGES/TG.po (3)

22-23: Normalize apostrophe style in "Jour de l'an"

The string contains a curly apostrophe (') instead of a straight one ('). For consistency, use straight apostrophes in all strings.

-msgid "Jour de l'an"
+msgid "Jour de l'an"

38-39: Normalize apostrophe style in "Fête de l'indépendance"

For consistency with other strings, replace the curly apostrophe with a straight one.

-msgid "Fête de l'indépendance"
+msgid "Fête de l'indépendance"

74-75: Normalize apostrophe style in "l'Aïd El-Fitr"

For consistency with other strings, replace the curly apostrophe with a straight one.

-msgid "l'Aïd El-Fitr"
+msgid "l'Aïd El-Fitr"
holidays/countries/togo.py (3)

82-82: Normalize apostrophe style in "Jour de l'an"

Replace the curly apostrophe with a straight one for consistency.

-        self._add_new_years_day(tr("Jour de l'an"))
+        self._add_new_years_day(tr("Jour de l'an"))

95-95: Normalize apostrophe style in "Fête de l'indépendance"

Replace the curly apostrophe with a straight one for consistency.

-        self._add_holiday_apr_27(tr("Fête de l'indépendance"))
+        self._add_holiday_apr_27(tr("Fête de l'indépendance"))

122-122: Normalize apostrophe style in "l'Aïd El-Fitr"

Replace the curly apostrophe with a straight one for consistency.

-        self._add_eid_al_fitr_day(tr("l'Aïd El-Fitr"))
+        self._add_eid_al_fitr_day(tr("l'Aïd El-Fitr"))
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 2e5004e and 5d8d2a2.

📒 Files selected for processing (3)
  • holidays/countries/togo.py (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/TG.po (1 hunks)
  • tests/countries/test_togo.py (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
holidays/locale/fr/LC_MESSAGES/TG.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.
holidays/countries/togo.py (2)
Learnt from: KJhellico
PR: vacanza/holidays#2525
File: holidays/countries/togo.py:0-0
Timestamp: 2025-05-04T10:29:46.760Z
Learning: When a country class in the holidays library uses additional categories beyond PUBLIC, the `supported_categories` tuple should contain all categories, including PUBLIC. Only when PUBLIC is the only category being used should it be omitted from `supported_categories`.
Learnt from: KJhellico
PR: vacanza/holidays#2437
File: holidays/countries/bhutan.py:27-30
Timestamp: 2025-04-08T14:46:10.656Z
Learning: For country classes in the holidays library, there's no need to explicitly specify `supported_categories = (PUBLIC,)` when PUBLIC is the only category being used, as it's already the default category inherited from HolidayBase.
🧬 Code Graph Analysis (1)
tests/countries/test_togo.py (2)
tests/common.py (7)
  • TestCase (28-338)
  • CommonCountryTests (356-374)
  • assertAliases (121-130)
  • assertNoHolidays (292-294)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
  • assertHolidays (228-230)
holidays/countries/togo.py (3)
  • Togo (26-133)
  • TG (136-137)
  • TGO (140-141)
🔇 Additional comments (8)
holidays/locale/fr/LC_MESSAGES/TG.po (3)

1-87: The TG.po file looks good overall

The French translations for Togo holidays are well-structured and correctly implemented. The message strings are empty as expected since French is the default language (no translation needed). Well done on providing comprehensive holiday coverage.


86-87: 🧹 Nitpick (assertive)

Normalize apostrophe style in "Anniversaire de l'attentat manqué contre Lomé"

Replace the curly apostrophe with a straight one for consistency.

-msgid "Anniversaire de l'attentat manqué contre Lomé"
+msgid "Anniversaire de l'attentat manqué contre Lomé"

Likely an incorrect or invalid review comment.


46-47: 🧹 Nitpick (assertive)

Normalize apostrophe style in "Fête de l'Ascension"

Replace the curly apostrophe with a straight one for consistency.

-msgid "Fête de l'Ascension"
+msgid "Fête de l'Ascension"

Likely an incorrect or invalid review comment.

tests/countries/test_togo.py (1)

1-240: Great test coverage for Togo holidays

The test suite is comprehensive and thoroughly tests all aspects of the Togo holiday implementation:

  • Tests for fixed holidays, movable holidays, and optional holidays
  • Verification of historically bounded holidays (Liberation Day)
  • Specific date assertions for Islamic holidays
  • Tests with and without estimated dates
  • Country alias tests
  • Tests for pre-independence period

This is a solid, well-structured test suite that ensures the correctness of the implementation.

holidays/countries/togo.py (4)

26-55: Excellent documentation and references

The class documentation is thorough and includes numerous references to validate the holiday implementations. This is exemplary practice for country holiday implementations, making it easy to verify and update the code in the future.


144-204: Well-structured Islamic holiday dates implementation

The TogoIslamicHolidays class is well-structured with explicit date mappings for Islamic holidays from 2010-2025. This approach ensures accuracy for known dates while falling back to calculated dates when necessary.


1-205: Overall excellent implementation of Togo holidays

The implementation is comprehensive, well-documented, and follows the library's patterns and best practices. The class hierarchy, initialization, and holiday population methods are structured correctly. The code includes both fixed and movable holidays, with proper handling of historically bounded holidays.


101-101: 🧹 Nitpick (assertive)

Normalize apostrophe style in "Fête de l'Ascension"

Replace the curly apostrophe with a straight one for consistency.

-        self._add_ascension_thursday(tr("Fête de l'Ascension"))
+        self._add_ascension_thursday(tr("Fête de l'Ascension"))

Likely an incorrect or invalid review comment.

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

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

235-252: 🧹 Nitpick (assertive)

Fix chronological order in 2025 holiday list

The order of holidays in test_2025 isn't strictly chronological. "Tabaski" (June 7) is listed after "Lundi de Pentecôte" (June 9).

Reorder the dates to maintain chronological order:

 ("2025-05-29", "Fête de l'Ascension"),
+("2025-06-07", "Tabaski"),
 ("2025-06-09", "Lundi de Pentecôte"),
-("2025-06-07", "Tabaski"),
 ("2025-06-21", "Fête des Martyrs"),
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5d8d2a2 and b5efd6c.

📒 Files selected for processing (1)
  • tests/countries/test_togo.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
tests/countries/test_togo.py (1)
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.
🔇 Additional comments (7)
tests/countries/test_togo.py (7)

20-26: Great test class setup for Togo holidays

The setup properly initializes test data from 1960 (Togo's independence) through 2050, which provides comprehensive test coverage. The class also creates specialized test instances for non-estimated holidays and optional holidays.


31-33: Good pre-independence check

The test correctly verifies that no holidays existed before Togo's independence in 1960, which is historically accurate.


38-41: Excellent historical boundary check

The test correctly handles the Liberation Day holiday that was observed from 1967 to 2013 and confirms it's not observed after 2013, respecting the historical constraints.


125-141: Thorough Islamic holiday testing

The tests for Ramadan, Eid al-Fitr, and Eid al-Adha properly check specific dates for multiple years and also verify correct behavior with the islamic_show_estimated=False parameter. This comprehensive approach ensures the Islamic lunar calendar dates are correctly mapped.

Also applies to: 143-164, 166-187


209-214: Good implementation of optional holiday tests

The optional holiday tests correctly verify that Mawlid Day and the Anniversary of the Failed Attack on Lomé are categorized as optional holidays, and the latter properly respects its historical starting point in 1987.

Also applies to: 202-207


216-252: 🧹 Nitpick (assertive)

Consider adding more yearly test cases

While you've included comprehensive tests for 2024 and 2025, adding test cases for additional years (perhaps historically significant years for Togo or years with unusual holiday patterns) would provide even more robust coverage.

Consider adding similar yearly test cases for years like 1960 (independence year), 1987 (when the anniversary of the failed attack was introduced), or other significant dates in Togo's history.

⛔ Skipped due to learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2386
File: tests/countries/test_nepal.py:499-536
Timestamp: 2025-04-05T06:49:06.217Z
Learning: In the holidays project, test files follow a dual testing approach: individual methods test specific holidays across multiple years, while comprehensive year-specific tests (e.g., `test_2025`) verify all holidays for a specific year in a single assertion. Both approaches serve different testing purposes and complement each other.
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.

96-111: 🧹 Nitpick (assertive)

Inconsistency between specific dates and range check in Whit Monday test

The test specifies particular dates for years 1960, 1970-1972, and 2020-2025, but the range check on line 111 covers all years from 1960 to 1973, which means years 1961-1969 and 1973 are tested in the range but don't have specific date assertions.

Either adjust the range to match the specific dates:

-self.assertHolidayName(name, range(1960, 1973))
+self.assertHolidayName(name, range(1960, 1961))
+self.assertHolidayName(name, range(1970, 1973))

Or add more specific dates for the missing years to ensure complete coverage.

⛔ Skipped due to learnings
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.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4944892 and 2c888bf.

📒 Files selected for processing (2)
  • holidays/countries/togo.py (1 hunks)
  • tests/countries/test_togo.py (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
tests/countries/test_togo.py (1)
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.
holidays/countries/togo.py (2)
Learnt from: KJhellico
PR: vacanza/holidays#2525
File: holidays/countries/togo.py:0-0
Timestamp: 2025-05-04T10:29:46.760Z
Learning: When a country class in the holidays library uses additional categories beyond PUBLIC, the `supported_categories` tuple should contain all categories, including PUBLIC. Only when PUBLIC is the only category being used should it be omitted from `supported_categories`.
Learnt from: KJhellico
PR: vacanza/holidays#2437
File: holidays/countries/bhutan.py:27-30
Timestamp: 2025-04-08T14:46:10.656Z
Learning: For country classes in the holidays library, there's no need to explicitly specify `supported_categories = (PUBLIC,)` when PUBLIC is the only category being used, as it's already the default category inherited from HolidayBase.
🧬 Code Graph Analysis (2)
tests/countries/test_togo.py (2)
tests/common.py (7)
  • TestCase (28-338)
  • CommonCountryTests (356-374)
  • assertAliases (121-130)
  • assertNoHolidays (292-294)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
  • assertHolidays (228-230)
holidays/countries/togo.py (3)
  • Togo (26-131)
  • TG (134-135)
  • TGO (138-139)
holidays/countries/togo.py (5)
holidays/calendars/islamic.py (1)
  • _CustomIslamicHolidays (3881-3882)
holidays/groups/christian.py (7)
  • ChristianHolidays (22-463)
  • _add_good_friday (308-317)
  • _add_easter_monday (259-268)
  • _add_ascension_thursday (119-127)
  • _add_whit_monday (432-441)
  • _add_all_saints_day (97-105)
  • _add_christmas_day (208-216)
holidays/groups/international.py (2)
  • InternationalHolidays (18-220)
  • _add_new_years_day (126-134)
holidays/groups/islamic.py (5)
  • IslamicHolidays (20-426)
  • _add_ramadan_beginning_day (386-396)
  • _add_eid_al_fitr_day (152-163)
  • _add_eid_al_adha_day (109-120)
  • _add_mawlid_day (329-339)
holidays/holiday_base.py (1)
  • HolidayBase (57-1301)
🔇 Additional comments (3)
holidays/countries/togo.py (3)

26-62: Good implementation of Togo holidays with thorough documentation.

The class is well-structured with excellent documentation, including extensive references for holiday date verification. The implementation correctly sets up Togo's country attributes including:

  • ISO code "TG"
  • French as default language
  • Proper supported categories (OPTIONAL, PUBLIC)
  • Independence year as start_year (1960)

142-202: Well-implemented custom Islamic holiday dates.

The TogoIslamicHolidays class correctly provides specific date mappings for Islamic holidays in Togo from 2010-2025, ensuring accurate representation of:

  • Eid al-Adha (Tabaski)
  • Eid al-Fitr
  • Mawlid
  • Ramadan beginning

This approach of using verified local dates rather than pure calculation is excellent for accuracy.


78-132: Holiday implementation is complete and well-structured.

The holiday population methods:

  • Correctly implement all Togo public and optional holidays
  • Use appropriate date calculation methods
  • Include date-conditional logic (Liberation Day: 1967-2013, Failed Attack Anniversary: 1987+)
  • Consistently use translation functions for internationalization

The code organization is clean and readable, following a logical progression through the calendar.

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.

And you forgot to modify holidays/countries/init.py.

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 b423fea and 9e18c68.

📒 Files selected for processing (6)
  • README.md (2 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/countries/togo.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/TG.po (1 hunks)
  • holidays/locale/fr/LC_MESSAGES/TG.po (1 hunks)
  • tests/countries/test_togo.py (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
holidays/countries/togo.py (2)
Learnt from: KJhellico
PR: vacanza/holidays#2525
File: holidays/countries/togo.py:0-0
Timestamp: 2025-05-04T10:29:46.760Z
Learning: When a country class in the holidays library uses additional categories beyond PUBLIC, the `supported_categories` tuple should contain all categories, including PUBLIC. Only when PUBLIC is the only category being used should it be omitted from `supported_categories`.
Learnt from: KJhellico
PR: vacanza/holidays#2437
File: holidays/countries/bhutan.py:27-30
Timestamp: 2025-04-08T14:46:10.656Z
Learning: For country classes in the holidays library, there's no need to explicitly specify `supported_categories = (PUBLIC,)` when PUBLIC is the only category being used, as it's already the default category inherited from HolidayBase.
tests/countries/test_togo.py (1)
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.
🧬 Code Graph Analysis (2)
holidays/countries/__init__.py (1)
holidays/countries/togo.py (3)
  • Togo (22-127)
  • TG (130-131)
  • TGO (134-135)
tests/countries/test_togo.py (2)
tests/common.py (8)
  • TestCase (28-338)
  • CommonCountryTests (356-374)
  • assertAliases (121-130)
  • assertNoHolidays (292-294)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
  • assertHolidays (228-230)
  • assertLocalizedHolidays (327-338)
holidays/countries/togo.py (3)
  • Togo (22-127)
  • TG (130-131)
  • TGO (134-135)
🔇 Additional comments (11)
holidays/countries/__init__.py (1)

167-167: Integrate Togo into the countries package

Adding from .togo import Togo, TG, TGO correctly registers the new Togo holiday calendar between TimorLeste and Tonga (alphabetical order).

README.md (2)

108-109: Update supported country count

The total supported countries count has been updated from 171 to 172 to reflect the addition of Togo.


1215-1220: Document Togo in the country table

The new table row for Togo (TG) with supported languages en_US and fr and category OPTIONAL aligns with other country entries.

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

1-101: French translation template added correctly

The French PO file for the Togo locale has been added with all message IDs. Ensure to populate msgstr entries as needed when finalizing translations.

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

30-102: English translations for Togo holidays are accurate

All French message IDs are correctly mapped to their English equivalents in msgstr.

holidays/countries/togo.py (5)

13-19: Imports are well-organized

Standard library import (gettext.gettext) is separated from project-specific imports, and the necessary holiday mixins and constants are correctly brought in.


22-24: Class docstring present

The Togo class includes a concise docstring referencing authoritative sources. Good context for maintainers.


60-72: Constructor initializes mixins properly

The __init__ method correctly chains the Christian, International, and Islamic holiday initializers before calling super().


74-83: Public holiday definitions follow patterns

The _populate_public_holidays method uses mixin methods wrapped with tr(), ensuring translation consistency.


121-127: Optional holidays implemented correctly

The optional holidays, including Prophet Mohammed's Birthday and the anniversary of the failed attack (post-1987), are correctly scoped.

tests/countries/test_togo.py (1)

1-284: LGTM! Well-constructed test module for Togo holidays.

The test module is comprehensive and follows the project's testing conventions correctly. It includes:

  • Tests for all public and optional holidays
  • Proper verification of fixed and movable dates
  • Chronologically ordered snapshots for 2024 and 2025
  • Good coverage of Islamic holidays with exact dates
  • Appropriate localization tests for both French and English

This is a solid implementation that meets all the requirements for holiday testing in the project.

@Roshan-1024 Roshan-1024 requested review from KJhellico and PPsyrius May 17, 2025 08:32
Co-authored-by: ~Jhellico <KJhellico@users.noreply.github.com>
Signed-off-by: Roshan Pradhan <roshanpradhan1024@gmail.com>
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 (2)
holidays/countries/togo.py (2)

56-57: Verify start_year matches independence history.

The comment notes independence on April 27, 1960, but start_year is set to 1961. Confirm if holidays were officially established starting from 1961 rather than 1960.


150-167: 🧹 Nitpick (assertive)

Add a class docstring for TogoIslamicHolidays.

Add a concise docstring explaining that this class provides custom Islamic holiday date mappings for Togo.

class TogoIslamicHolidays(_CustomIslamicHolidays):
+    """Custom Islamic holiday calendar for Togo with explicit date mappings."""
    EID_AL_ADHA_DATES = {
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between e499330 and dc0811a.

📒 Files selected for processing (1)
  • holidays/countries/togo.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
holidays/countries/togo.py (5)
holidays/calendars/islamic.py (1)
  • _CustomIslamicHolidays (3881-3882)
holidays/groups/christian.py (6)
  • ChristianHolidays (22-463)
  • _add_easter_monday (259-268)
  • _add_ascension_thursday (119-127)
  • _add_whit_monday (432-441)
  • _add_all_saints_day (97-105)
  • _add_christmas_day (208-216)
holidays/groups/international.py (2)
  • InternationalHolidays (18-220)
  • _add_new_years_day (126-134)
holidays/groups/islamic.py (5)
  • IslamicHolidays (20-426)
  • _add_ramadan_beginning_day (386-396)
  • _add_eid_al_fitr_day (152-163)
  • _add_eid_al_adha_day (109-120)
  • _add_mawlid_day (329-339)
holidays/holiday_base.py (1)
  • HolidayBase (57-1301)
🔇 Additional comments (1)
holidays/countries/togo.py (1)

1-211: Well-structured implementation with comprehensive documentation.

The implementation follows library conventions with thorough documentation, references to sources, correct holiday definitions, and appropriate handling of subdivisions. The use of archived web links and detailed date mappings shows attention to detail.

@Roshan-1024 Roshan-1024 requested a review from KJhellico May 18, 2025 18:31
Signed-off-by: ~Jhellico <KJhellico@users.noreply.github.com>
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
3.7% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copy link
Collaborator

@PPsyrius PPsyrius left a comment

Choose a reason for hiding this comment

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

LGTM 🇹🇬

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

@arkid15r arkid15r added this pull request to the merge queue May 19, 2025
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.

@Roshan-1024 thanks for another great contribution 👍

I'm merging this to include it into today's v0.73 release

Merged via the queue into vacanza:dev with commit a27dc16 May 19, 2025
32 of 33 checks passed
@KJhellico KJhellico mentioned this pull request May 19, 2025
Wasif-Shahzad pushed a commit to Wasif-Shahzad/holidays that referenced this pull request May 21, 2025
Signed-off-by: Roshan Pradhan <roshanpradhan1024@gmail.com>
Signed-off-by: ~Jhellico <KJhellico@users.noreply.github.com>
Co-authored-by: ~Jhellico <KJhellico@users.noreply.github.com>
ShalomDee pushed a commit to ShalomDee/holidays that referenced this pull request Jun 2, 2025
Signed-off-by: Roshan Pradhan <roshanpradhan1024@gmail.com>
Signed-off-by: ~Jhellico <KJhellico@users.noreply.github.com>
Co-authored-by: ~Jhellico <KJhellico@users.noreply.github.com>
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 Togo holidays

4 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载