Repository: vacanza/holidays
Pull request #2593 (2025-06-04 09:53:04)

Add Senegal holidays
<!--
  Thanks for contributing to holidays!
-->

## Proposed change

<!--

-->

Add Senegal holidays.
Resolves [#1266](https://github.com/vacanza/holidays/issues/1266)

## Type of change

<!--
  Type of change you want to introduce. Please, check one (1) box only!
  If your PR requires multiple boxes to be checked, most likely it needs to
  be split into multiple PRs.
-->

- [x] 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

<!--
  Put an `x` in the boxes that apply. You can change them after PR is created.
-->

- [x] I've followed the [contributing guidelines][contributing-guidelines]
- [x] I've successfully run `make check`, all checks and tests are green

<!--
  Thanks again for your contribution!
-->

[contributing-guidelines]: https://github.com/vacanza/holidays/blob/dev/CONTRIBUTING.md
[docs]: https://github.com/vacanza/holidays/tree/dev/docs/source


coderabbitai[bot]: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->

> [!NOTE]
> Currently processing new changes in this PR. This may take a few minutes, please wait...
> 
> <details>
> <summary>📥 Commits</summary>
> 
> Reviewing files that changed from the base of the PR and between d2fde708d52618cb4b595091ded53b22ea044061 and 758c02a03fcf347434d53f28be9ec022d191c226.
> 
> </details>
> 
> <details>
> <summary>📒 Files selected for processing (10)</summary>
> 
> * `README.md` (2 hunks)
> * `holidays/calendars/islamic.py` (3 hunks)
> * `holidays/countries/__init__.py` (1 hunks)
> * `holidays/countries/senegal.py` (1 hunks)
> * `holidays/groups/islamic.py` (1 hunks)
> * `holidays/locale/en_US/LC_MESSAGES/SN.po` (1 hunks)
> * `holidays/locale/fr/LC_MESSAGES/SN.po` (1 hunks)
> * `holidays/registry.py` (1 hunks)
> * `scripts/calendar/islamic_generator.py` (1 hunks)
> * `tests/countries/test_senegal.py` (1 hunks)
> 
> </details>
> 
> ```ascii
>  __________________________________________
> < Lint long and prosper with cleaner code. >
>  ------------------------------------------
>   \
>    \   \
>         \ /\
>         ( )
>       .( o ).
> ```

<!-- end of auto-generated comment: review in progress by coderabbit.ai -->
<!-- usage_tips_start -->

> [!TIP]
> <details>
> <summary>You can generate walkthrough in a markdown collapsible section to save space.</summary>
> 
> Enable the `reviews.collapse_walkthrough` setting in your project's settings in CodeRabbit to generate walkthrough in a markdown collapsible section.
> 
> </details>

<!-- usage_tips_end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=vacanza/holidays&utm_content=2593):

- 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](https://www.coderabbit.ai/contact-us/support) 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](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in 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](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)


Wasif-Shahzad: it supposedly still exists and are de facto grant "Bridge Holiday" (Jour de Pont) 

What do you mean by this? @PPsyrius 
timeanddate.com also has observances for Eid al-Fitr and Eid al-Adha btw

PPsyrius: What I meant is that the `SUN_TO_NEXT_MON` observances as stated in Law 74-52 are still in place for both Eid al-Fitr and Eid al-Adha in Senegal.

For others, i.e. [Decree 2018-1942](https://www.juriafrica.com/lex/decret-2018-1942-26-octobre-2018-48947.htm) and [Conseil des ministres du 22 décembre 2022](https://primature.sn/publications/conseil-des-ministres/conseil-des-ministres-du-22-decembre-2022) - let's put those in as special holidays for now.
sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)


KJhellico: Let's summarize the necessary changes.

1964 (Law 63-51):
\+ July 14: Fête de l'Indépendance

1975 (Law 74-52):
\- July 14
\+ Apr 4: Fête de l'Indépendance

1983 (Law 83-54):
\+ Feb 1: Fête de la Confédération de la Sénégambie
\+ Tamxarit

1990 (Law 89-41):
\- Feb 1

2014 (Law 2013-06):
\+ Grand Magal de Touba

Names:
- Tamxarit
- Journée du Maouloud
- Journée de la Korité
- Journée de la Tabaski
- Jeudi de l'Ascension

I propose to keep Assomption, Toussaint, and Noël, even though they have different names in laws (except, perhaps, Journée de la Toussaint).
sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)


Wasif-Shahzad: @KJhellico @PPsyrius Hopefully its LGTM now... :smiley: 
sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)


sonarqubecloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2593&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2593&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2593)



Patch:
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 780484fd..763531ca 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -152,6 +152,7 @@ Tudor Văran
 Victor Luna
 Victor Miti
 Ville Skyttä
+Vilmos Prokaj
 Vu Nhat Chuong
 Wasif Shahzad
 Youhei Sakurai
diff --git a/README.md b/README.md
index a72ed72e..00f1a5df 100644
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ and detailed information.
 
 ## Available Countries
 
-We currently support 185 country codes. The standard way to refer to a country is by using its [ISO
+We currently support 186 country codes. The standard way to refer to a country is by using its [ISO
 3166-1 alpha-2 code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes), the same used
 for domain names, and for a subdivision its [ISO 3166-2
 code](https://en.wikipedia.org/wiki/ISO_3166-2). Some countries have common or foreign names or
@@ -1169,6 +1169,13 @@ any) in brackets, available languages and additional holiday categories. All cou
 <td></td>
 </tr>
 <tr>
+<td>Senegal</td>
+<td>SN</td>
+<td></td>
+<td>en_US, <strong>fr_SN</strong></td>
+<td></td>
+</tr>
+<tr>
 <td>Serbia</td>
 <td>RS</td>
 <td></td>
diff --git a/holidays/calendars/islamic.py b/holidays/calendars/islamic.py
index 99ad415c..807dbd04 100644
--- a/holidays/calendars/islamic.py
+++ b/holidays/calendars/islamic.py
@@ -26,6 +26,7 @@ EID_AL_ADHA = "EID_AL_ADHA"
 EID_AL_FITR = "EID_AL_FITR"
 EID_AL_GHADIR = "EID_AL_GHADIR"
 FATIMA_DEATH = "FATIMA_DEATH"
+GRAND_MAGAL_OF_TOUBA = "GRAND_MAGAL_OF_TOUBA"
 HARI_HOL_JOHOR = "HARI_HOL_JOHOR"
 HASAN_AL_ASKARI_DEATH = "HASAN_AL_ASKARI_DEATH"
 HIJRI_NEW_YEAR = "HIJRI_NEW_YEAR"
@@ -1451,6 +1452,163 @@ class _IslamicLunar:
         2077: (APR, 26),
     }
 
+    GRAND_MAGAL_OF_TOUBA_DATES = {
+        1924: (SEP, 17),
+        1925: (SEP, 7),
+        1926: (AUG, 27),
+        1927: (AUG, 16),
+        1928: (AUG, 4),
+        1929: (JUL, 25),
+        1930: (JUL, 14),
+        1931: (JUL, 4),
+        1932: (JUN, 23),
+        1933: (JUN, 12),
+        1934: (JUN, 1),
+        1935: (MAY, 21),
+        1936: (MAY, 10),
+        1937: (APR, 29),
+        1938: (APR, 18),
+        1939: (APR, 8),
+        1940: (MAR, 27),
+        1941: (MAR, 16),
+        1942: (MAR, 6),
+        1943: (FEB, 23),
+        1944: (FEB, 12),
+        1945: (FEB, 1),
+        1946: (JAN, 21),
+        1947: ((JAN, 11), (DEC, 31)),
+        1948: (DEC, 19),
+        1949: (DEC, 9),
+        1950: (NOV, 29),
+        1951: (NOV, 18),
+        1952: (NOV, 6),
+        1953: (OCT, 26),
+        1954: (OCT, 16),
+        1955: (OCT, 6),
+        1956: (SEP, 23),
+        1957: (SEP, 13),
+        1958: (SEP, 3),
+        1959: (AUG, 22),
+        1960: (AUG, 11),
+        1961: (JUL, 31),
+        1962: (JUL, 20),
+        1963: (JUL, 9),
+        1964: (JUN, 28),
+        1965: (JUN, 17),
+        1966: (JUN, 7),
+        1967: (MAY, 27),
+        1968: (MAY, 15),
+        1969: (MAY, 5),
+        1970: (APR, 25),
+        1971: (APR, 14),
+        1972: (APR, 2),
+        1973: (MAR, 23),
+        1974: (MAR, 12),
+        1975: (MAR, 1),
+        1976: (FEB, 18),
+        1977: (FEB, 6),
+        1978: (JAN, 27),
+        1979: (JAN, 16),
+        1980: ((JAN, 6), (DEC, 25)),
+        1981: (DEC, 14),
+        1982: (DEC, 3),
+        1983: (NOV, 22),
+        1984: (NOV, 11),
+        1985: (NOV, 1),
+        1986: (OCT, 21),
+        1987: (OCT, 11),
+        1988: (SEP, 29),
+        1989: (SEP, 18),
+        1990: (SEP, 7),
+        1991: (AUG, 28),
+        1992: (AUG, 16),
+        1993: (AUG, 6),
+        1994: (JUL, 26),
+        1995: (JUL, 16),
+        1996: (JUL, 4),
+        1997: (JUN, 23),
+        1998: (JUN, 12),
+        1999: (JUN, 2),
+        2000: (MAY, 22),
+        2001: (MAY, 12),
+        2002: (MAY, 1),
+        2003: (APR, 20),
+        2004: (APR, 8),
+        2005: (MAR, 28),
+        2006: (MAR, 18),
+        2007: (MAR, 8),
+        2008: (FEB, 25),
+        2009: (FEB, 13),
+        2010: (FEB, 2),
+        2011: (JAN, 22),
+        2012: ((JAN, 12), (DEC, 31)),
+        2013: (DEC, 21),
+        2014: (DEC, 10),
+        2015: (NOV, 30),
+        2016: (NOV, 18),
+        2017: (NOV, 7),
+        2018: (OCT, 27),
+        2019: (OCT, 17),
+        2020: (OCT, 5),
+        2021: (SEP, 25),
+        2022: (SEP, 14),
+        2023: (SEP, 3),
+        2024: (AUG, 22),
+        2025: (AUG, 12),
+        2026: (AUG, 1),
+        2027: (JUL, 22),
+        2028: (JUL, 11),
+        2029: (JUN, 30),
+        2030: (JUN, 19),
+        2031: (JUN, 8),
+        2032: (MAY, 27),
+        2033: (MAY, 17),
+        2034: (MAY, 7),
+        2035: (APR, 26),
+        2036: (APR, 15),
+        2037: (APR, 4),
+        2038: (MAR, 24),
+        2039: (MAR, 13),
+        2040: (MAR, 2),
+        2041: (FEB, 19),
+        2042: (FEB, 9),
+        2043: (JAN, 29),
+        2044: (JAN, 19),
+        2045: ((JAN, 7), (DEC, 27)),
+        2046: (DEC, 16),
+        2047: (DEC, 6),
+        2048: (NOV, 24),
+        2049: (NOV, 14),
+        2050: (NOV, 3),
+        2051: (OCT, 23),
+        2052: (OCT, 11),
+        2053: (SEP, 30),
+        2054: (SEP, 20),
+        2055: (SEP, 10),
+        2056: (AUG, 29),
+        2057: (AUG, 18),
+        2058: (AUG, 7),
+        2059: (JUL, 28),
+        2060: (JUL, 16),
+        2061: (JUL, 6),
+        2062: (JUN, 25),
+        2063: (JUN, 15),
+        2064: (JUN, 3),
+        2065: (MAY, 23),
+        2066: (MAY, 12),
+        2067: (MAY, 2),
+        2068: (APR, 20),
+        2069: (APR, 10),
+        2070: (MAR, 31),
+        2071: (MAR, 20),
+        2072: (MAR, 8),
+        2073: (FEB, 25),
+        2074: (FEB, 14),
+        2075: (FEB, 4),
+        2076: (JAN, 24),
+        2077: (JAN, 13),
+    }
+
     HARI_HOL_JOHOR_DATES = {
         1924: (SEP, 5),
         1925: (AUG, 26),
@@ -3832,6 +3990,9 @@ class _IslamicLunar:
     def fatima_death_dates(self, year: int) -> Iterable[tuple[date, bool]]:
         return self._get_holiday(FATIMA_DEATH, year)
 
+    def grand_magal_of_touba_dates(self, year: int) -> Iterable[tuple[date, bool]]:
+        return self._get_holiday(GRAND_MAGAL_OF_TOUBA, year)
+
     def hari_hol_johor_dates(self, year: int) -> Iterable[tuple[date, bool]]:
         return self._get_holiday(HARI_HOL_JOHOR, year)
 
diff --git a/holidays/countries/__init__.py b/holidays/countries/__init__.py
index cde4cc9f..6b20090b 100644
--- a/holidays/countries/__init__.py
+++ b/holidays/countries/__init__.py
@@ -163,6 +163,7 @@ from holidays.countries.samoa import Samoa, WS, WSM
 from holidays.countries.san_marino import SanMarino, SM, SMR
 from holidays.countries.sao_tome_and_principe import SaoTomeAndPrincipe, ST, STP
 from holidays.countries.saudi_arabia import SaudiArabia, SA, SAU
+from holidays.countries.senegal import Senegal, SN, SEN
 from holidays.countries.serbia import Serbia, RS, SRB
 from holidays.countries.seychelles import Seychelles, SC, SYC
 from holidays.countries.sierra_leone import SierraLeone, SL, SLE
diff --git a/holidays/countries/afghanistan.py b/holidays/countries/afghanistan.py
index b0075733..6af54636 100644
--- a/holidays/countries/afghanistan.py
+++ b/holidays/countries/afghanistan.py
@@ -50,7 +50,7 @@ class Afghanistan(HolidayBase, InternationalHolidays, IslamicHolidays, PersianCa
     start_year = 1919
     weekend = {FRI, SAT}
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/albania.py b/holidays/countries/albania.py
index 408897b1..9b9c8b2f 100644
--- a/holidays/countries/albania.py
+++ b/holidays/countries/albania.py
@@ -47,7 +47,7 @@ class Albania(
     # Law No. 7651 from 21.12.1992.
     start_year = 1993
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/algeria.py b/holidays/countries/algeria.py
index 6a0f9d53..f6bf0ba6 100644
--- a/holidays/countries/algeria.py
+++ b/holidays/countries/algeria.py
@@ -32,7 +32,7 @@ class Algeria(HolidayBase, InternationalHolidays, IslamicHolidays):
     estimated_label = tr("(تقدير) %s")
     supported_languages = ("ar", "en_US", "fr")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/argentina.py b/holidays/countries/argentina.py
index 8ae1a52a..2a5480ee 100644
--- a/holidays/countries/argentina.py
+++ b/holidays/countries/argentina.py
@@ -206,7 +206,7 @@ class Argentina(
     supported_languages = ("en_US", "es", "uk")
     supported_categories = (ARMENIAN, BANK, GOVERNMENT, HEBREW, ISLAMIC, PUBLIC)
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/azerbaijan.py b/holidays/countries/azerbaijan.py
index 9c935dfb..49d126b2 100644
--- a/holidays/countries/azerbaijan.py
+++ b/holidays/countries/azerbaijan.py
@@ -45,7 +45,7 @@ class Azerbaijan(ObservedHolidayBase, InternationalHolidays, IslamicHolidays, St
     supported_languages = ("az", "en_US", "uk")
     start_year = 1990
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/bahrain.py b/holidays/countries/bahrain.py
index aebaf018..177d6677 100644
--- a/holidays/countries/bahrain.py
+++ b/holidays/countries/bahrain.py
@@ -33,7 +33,7 @@ class Bahrain(HolidayBase, InternationalHolidays, IslamicHolidays):
     supported_languages = ("ar", "en_US")
     weekend = {FRI, SAT}
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/benin.py b/holidays/countries/benin.py
index 815de2d3..6edc3788 100644
--- a/holidays/countries/benin.py
+++ b/holidays/countries/benin.py
@@ -75,7 +75,7 @@ class Benin(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolida
     supported_categories = (PUBLIC, WORKDAY)
     supported_languages = ("en_US", "fr_BJ")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/bosnia_and_herzegovina.py b/holidays/countries/bosnia_and_herzegovina.py
index 21fb8c33..0750069e 100644
--- a/holidays/countries/bosnia_and_herzegovina.py
+++ b/holidays/countries/bosnia_and_herzegovina.py
@@ -75,7 +75,7 @@ class BosniaAndHerzegovina(
     }
     supported_languages = ("bs", "en_US", "sr", "uk")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/brunei.py b/holidays/countries/brunei.py
index c6f5417b..0c1d5e69 100644
--- a/holidays/countries/brunei.py
+++ b/holidays/countries/brunei.py
@@ -116,7 +116,7 @@ class Brunei(
     # Available post-Independence from 1984 afterwards
     start_year = 1984
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/burkina_faso.py b/holidays/countries/burkina_faso.py
index 177ba723..8faf867f 100644
--- a/holidays/countries/burkina_faso.py
+++ b/holidays/countries/burkina_faso.py
@@ -29,7 +29,7 @@ class BurkinaFaso(ObservedHolidayBase, ChristianHolidays, InternationalHolidays,
     # gained independence from France.
     start_year = 1961
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/burundi.py b/holidays/countries/burundi.py
index 02dded82..1093b258 100644
--- a/holidays/countries/burundi.py
+++ b/holidays/countries/burundi.py
@@ -29,7 +29,7 @@ class Burundi(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, Isl
     observed_label = "%s (observed)"
     start_year = 1962
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/cameroon.py b/holidays/countries/cameroon.py
index 81489b6f..08e42860 100644
--- a/holidays/countries/cameroon.py
+++ b/holidays/countries/cameroon.py
@@ -37,7 +37,7 @@ class Cameroon(
     # On 1 January 1960, French Cameroun gained independence from France.
     start_year = 1960
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/chad.py b/holidays/countries/chad.py
index c0472365..05298786 100644
--- a/holidays/countries/chad.py
+++ b/holidays/countries/chad.py
@@ -36,7 +36,7 @@ class Chad(
     # On 11 August 1960, Chad gained independence from France.
     start_year = 1961
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/cocos_islands.py b/holidays/countries/cocos_islands.py
index d39a482b..d415f228 100644
--- a/holidays/countries/cocos_islands.py
+++ b/holidays/countries/cocos_islands.py
@@ -72,7 +72,7 @@ class CocosIslands(
     # Act of Self Determination 1984.
     start_year = 1985
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/djibouti.py b/holidays/countries/djibouti.py
index 28772518..bbf12f04 100644
--- a/holidays/countries/djibouti.py
+++ b/holidays/countries/djibouti.py
@@ -29,7 +29,7 @@ class Djibouti(HolidayBase, ChristianHolidays, IslamicHolidays, InternationalHol
     # On 27 June 1977, Djibouti gained independence from France.
     start_year = 1978
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/egypt.py b/holidays/countries/egypt.py
index c89b760f..f1151fc1 100644
--- a/holidays/countries/egypt.py
+++ b/holidays/countries/egypt.py
@@ -28,7 +28,7 @@ class Egypt(HolidayBase, ChristianHolidays, IslamicHolidays, InternationalHolida
     supported_languages = ("ar", "en_US")
     weekend = {FRI, SAT}
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/ethiopia.py b/holidays/countries/ethiopia.py
index a50bcf99..29d30fa6 100644
--- a/holidays/countries/ethiopia.py
+++ b/holidays/countries/ethiopia.py
@@ -58,7 +58,7 @@ class Ethiopia(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHol
 
         return isleap(self._year + 1)
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/fiji.py b/holidays/countries/fiji.py
index 94ff0c7e..80f47153 100644
--- a/holidays/countries/fiji.py
+++ b/holidays/countries/fiji.py
@@ -70,7 +70,7 @@ class Fiji(
     # Act No. 13 of 2015
     start_year = 2016
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/gabon.py b/holidays/countries/gabon.py
index 09ee54fa..039097ea 100644
--- a/holidays/countries/gabon.py
+++ b/holidays/countries/gabon.py
@@ -30,7 +30,7 @@ class Gabon(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolida
     # On 17 August 1960, Gabon gained independence from France.
     start_year = 1961
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/ghana.py b/holidays/countries/ghana.py
index 066bc677..e2008ff8 100644
--- a/holidays/countries/ghana.py
+++ b/holidays/countries/ghana.py
@@ -32,7 +32,7 @@ class Ghana(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, Islam
     observed_estimated_label = "%s (observed, estimated)"
     start_year = 1957
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/guinea.py b/holidays/countries/guinea.py
index 3f9cad41..389862ca 100644
--- a/holidays/countries/guinea.py
+++ b/holidays/countries/guinea.py
@@ -48,7 +48,7 @@ class Guinea(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, Isla
     # Guinea gained independence from France on October 2, 1958.
     start_year = 1959
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/hungary.py b/holidays/countries/hungary.py
index d9e37472..18d7b901 100644
--- a/holidays/countries/hungary.py
+++ b/holidays/countries/hungary.py
@@ -117,6 +117,21 @@ class HungaryStaticHolidays:
     """Hungary special holidays.
 
     References:
+        * [1991](https://archive.org/details/7-1990-xii-27-mum-rendelet)
+        * [1992](https://web.archive.org/web/20250526085935/https://jogkodex.hu/jsz/1992_3_mum_rendelet_5937748)
+        * [1993](https://web.archive.org/web/20250526090343/https://jogkodex.hu/jsz/1992_7_mum_rendelet_7815697)
+        * [1994](https://web.archive.org/web/20250526090541/https://jogkodex.hu/jsz/1993_3_mum_rendelet_3120363)
+        * [1997](https://web.archive.org/web/20250526090817/https://jogkodex.hu/jsz/1996_11_mum_rendelet_3554324)
+        * [1998](https://web.archive.org/web/20250526091318/https://jogkodex.hu/jsz/1997_18_mum_rendelet_7493439)
+        * [1999](https://web.archive.org/web/20250526093916/https://jogkodex.hu/jsz/1998_3_szcsm_rendelet_7336830)
+        * [2001](https://archive.org/details/43-2000-xii-18-gm-rendelet)
+        * [2002](https://web.archive.org/web/20250526071659/https://jogkodex.hu/jsz/2001_25_gm_rendelet_9200619)
+        * [2003](https://web.archive.org/web/20250526071517/https://jogkodex.hu/jsz/2002_2_fmm_rendelet_1831209)
+        * [2004](https://web.archive.org/web/20250526071310/https://jogkodex.hu/jsz/2003_9_fmm_rendelet_8666269)
+        * [2005](https://web.archive.org/web/20250526071135/https://jogkodex.hu/jsz/2004_25_fmm_rendelet_4309634)
+        * [2007](https://web.archive.org/web/20250526064108/https://jogkodex.hu/jsz/2006_4_szmm_rendelet_8628960)
+        * [2008](https://web.archive.org/web/20250526051643/https://jogkodex.hu/jsz/2007_27_szmm_rendelet_3904252)
+        * [2009](https://web.archive.org/web/20250526051816/https://jogkodex.hu/jsz/2008_16_szmm_rendelet_7668376)
         * [2010](https://web.archive.org/web/20250428204804/https://njt.hu/jogszabaly/2009-20-20-1X)
         * [2011](https://web.archive.org/web/20250428204915/https://njt.hu/jogszabaly/2010-7-20-2X)
         * [2012](https://web.archive.org/web/20250428204812/https://njt.hu/jogszabaly/2011-39-20-2X)
@@ -131,6 +146,7 @@ class HungaryStaticHolidays:
         * [2022](https://web.archive.org/web/20241107133627/https://njt.hu/jogszabaly/2021-23-20-7Q)
         * [2024](https://web.archive.org/web/20241105131832/https://njt.hu/jogszabaly/2023-15-20-8P)
         * [2025](https://web.archive.org/web/20241219165144/https://njt.hu/jogszabaly/2024-11-20-2X)
+        * [2026](https://web.archive.org/web/20250526083742/https://jogkodex.hu/jsz/2025_10_ngm_rendelet_5591314)
     """
 
     # Substituted date format.
@@ -138,6 +154,67 @@ class HungaryStaticHolidays:
     # Day off (substituted from %s).
     substituted_label = tr("Pihenőnap (%s-től helyettesítve)")
     special_public_holidays = {
+        1991: (AUG, 19, AUG, 17),
+        1992: (
+            (AUG, 21, AUG, 29),
+            (DEC, 24, DEC, 19),
+        ),
+        1993: (DEC, 24, DEC, 18),
+        1994: (MAR, 14, MAR, 12),
+        1997: (
+            (MAY, 2, APR, 26),
+            (OCT, 24, OCT, 18),
+            (DEC, 24, DEC, 20),
+        ),
+        1998: (
+            (JAN, 2, JAN, 10),
+            (AUG, 21, AUG, 15),
+            (DEC, 24, DEC, 19),
+        ),
+        1999: (DEC, 24, DEC, 18),
+        2001: (
+            (MAR, 16, MAR, 10),
+            (APR, 30, APR, 28),
+            (OCT, 22, OCT, 20),
+            (NOV, 2, OCT, 27),
+            (DEC, 24, DEC, 22),
+            (DEC, 31, DEC, 29),
+        ),
+        2002: (
+            (AUG, 19, AUG, 10),
+            (DEC, 24, DEC, 28),
+        ),
+        2003: (
+            (MAY, 2, APR, 26),
+            (OCT, 24, OCT, 18),
+            (DEC, 24, DEC, 13),
+        ),
+        2004: (
+            (JAN, 2, JAN, 10),
+            (DEC, 24, DEC, 18),
+        ),
+        2005: (
+            (MAR, 14, MAR, 19),
+            (OCT, 31, NOV, 5),
+        ),
+        2007: (
+            (MAR, 16, MAR, 10),
+            (APR, 30, APR, 21),
+            (OCT, 22, OCT, 20),
+            (NOV, 2, OCT, 27),
+            (DEC, 24, DEC, 22),
+            (DEC, 31, DEC, 29),
+        ),
+        2008: (
+            (MAY, 2, APR, 26),
+            (OCT, 24, OCT, 18),
+            (DEC, 24, DEC, 20),
+        ),
+        2009: (
+            (JAN, 2, MAR, 28),
+            (AUG, 21, AUG, 29),
+            (DEC, 24, DEC, 19),
+        ),
         2010: (DEC, 24, DEC, 11),
         2011: (
             (MAR, 14, MAR, 19),
@@ -202,4 +279,9 @@ class HungaryStaticHolidays:
             (OCT, 24, OCT, 18),
             (DEC, 24, DEC, 13),
         ),
+        2026: (
+            (JAN, 2, JAN, 10),
+            (AUG, 21, AUG, 8),
+            (DEC, 24, DEC, 12),
+        ),
     }
diff --git a/holidays/countries/india.py b/holidays/countries/india.py
index 69dfbbea..45875d4c 100644
--- a/holidays/countries/india.py
+++ b/holidays/countries/india.py
@@ -150,7 +150,7 @@ class India(
         "OR",  # Orissa.
     )
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/indonesia.py b/holidays/countries/indonesia.py
index 8f4e750d..2b9e556c 100644
--- a/holidays/countries/indonesia.py
+++ b/holidays/countries/indonesia.py
@@ -63,7 +63,7 @@ class Indonesia(
     supported_categories = (GOVERNMENT, PUBLIC)
     start_year = 1946
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/iran.py b/holidays/countries/iran.py
index eb845028..0334937b 100644
--- a/holidays/countries/iran.py
+++ b/holidays/countries/iran.py
@@ -51,7 +51,7 @@ class Iran(HolidayBase, IslamicHolidays, PersianCalendarHolidays):
     start_year = 1980
     weekend = {FRI}
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/ivory_coast.py b/holidays/countries/ivory_coast.py
index ab6bbe55..e3d6d09d 100644
--- a/holidays/countries/ivory_coast.py
+++ b/holidays/countries/ivory_coast.py
@@ -60,7 +60,7 @@ class IvoryCoast(
     start_year = 1997
     supported_languages = ("en_CI", "en_US", "fr")
 
-    def __init__(self, islamic_show_estimated: bool = False, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = False, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/jordan.py b/holidays/countries/jordan.py
index bb6d57a6..d25cbc50 100644
--- a/holidays/countries/jordan.py
+++ b/holidays/countries/jordan.py
@@ -31,7 +31,7 @@ class Jordan(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolid
     estimated_label = tr("(تقدير) %s")
     supported_languages = ("ar", "en_US")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/kazakhstan.py b/holidays/countries/kazakhstan.py
index 498b18ec..1b771fcd 100644
--- a/holidays/countries/kazakhstan.py
+++ b/holidays/countries/kazakhstan.py
@@ -51,7 +51,7 @@ class Kazakhstan(
     # Kazakhstan declared its sovereignty on 25 October 1990.
     start_year = 1991
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/kenya.py b/holidays/countries/kenya.py
index c30846ce..ad1aa44a 100644
--- a/holidays/countries/kenya.py
+++ b/holidays/countries/kenya.py
@@ -54,7 +54,7 @@ class Kenya(
     # Kenya gained independence on December 12, 1963.
     start_year = 1964
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/kuwait.py b/holidays/countries/kuwait.py
index 8a3431a6..d0611f22 100644
--- a/holidays/countries/kuwait.py
+++ b/holidays/countries/kuwait.py
@@ -32,7 +32,7 @@ class Kuwait(HolidayBase, InternationalHolidays, IslamicHolidays):
     estimated_label = tr("(تقدير) %s")
     supported_languages = ("ar", "en_US")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/kyrgyzstan.py b/holidays/countries/kyrgyzstan.py
index a1ae4f8c..87bc5604 100644
--- a/holidays/countries/kyrgyzstan.py
+++ b/holidays/countries/kyrgyzstan.py
@@ -24,7 +24,7 @@ class Kyrgyzstan(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicH
 
     country = "KG"
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/malaysia.py b/holidays/countries/malaysia.py
index 96f2c61b..8d2d196b 100644
--- a/holidays/countries/malaysia.py
+++ b/holidays/countries/malaysia.py
@@ -144,7 +144,7 @@ class Malaysia(
     }
     supported_languages = ("en_US", "ms_MY", "th")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/maldives.py b/holidays/countries/maldives.py
index 964559d6..6b31a08a 100644
--- a/holidays/countries/maldives.py
+++ b/holidays/countries/maldives.py
@@ -27,7 +27,7 @@ class Maldives(HolidayBase, InternationalHolidays, IslamicHolidays):
     country = "MV"
     weekend = {FRI, SAT}
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/mauritania.py b/holidays/countries/mauritania.py
index 97e1a772..fdc76bc5 100644
--- a/holidays/countries/mauritania.py
+++ b/holidays/countries/mauritania.py
@@ -26,7 +26,7 @@ class Mauritania(HolidayBase, InternationalHolidays, IslamicHolidays):
     country = "MR"
     weekend = {FRI, SAT}
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/montenegro.py b/holidays/countries/montenegro.py
index cb949ec2..251135b2 100644
--- a/holidays/countries/montenegro.py
+++ b/holidays/countries/montenegro.py
@@ -54,7 +54,7 @@ class Montenegro(
     supported_categories = (CATHOLIC, ISLAMIC, HEBREW, ORTHODOX, PUBLIC, WORKDAY)
     start_year = 2007
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/morocco.py b/holidays/countries/morocco.py
index fa5210fe..f4a26262 100644
--- a/holidays/countries/morocco.py
+++ b/holidays/countries/morocco.py
@@ -30,7 +30,7 @@ class Morocco(HolidayBase, InternationalHolidays, IslamicHolidays):
     estimated_label = tr("(تقدير) %s")
     supported_languages = ("ar", "en_US", "fr")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/nepal.py b/holidays/countries/nepal.py
index 24736a7a..23c57fcd 100644
--- a/holidays/countries/nepal.py
+++ b/holidays/countries/nepal.py
@@ -52,7 +52,7 @@ class Nepal(
     start_year = 2010
     supported_categories = (PUBLIC, WORKDAY)
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/niger.py b/holidays/countries/niger.py
index 2f07095b..46db78bb 100644
--- a/holidays/countries/niger.py
+++ b/holidays/countries/niger.py
@@ -69,7 +69,7 @@ class Niger(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, Islam
     start_year = 1960
     weekend = {SUN}
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/nigeria.py b/holidays/countries/nigeria.py
index 3521932e..4541a872 100644
--- a/holidays/countries/nigeria.py
+++ b/holidays/countries/nigeria.py
@@ -33,7 +33,7 @@ class Nigeria(
     observed_label = "%s (observed)"
     start_year = 1979
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/north_macedonia.py b/holidays/countries/north_macedonia.py
index a7f83c32..7956cca9 100644
--- a/holidays/countries/north_macedonia.py
+++ b/holidays/countries/north_macedonia.py
@@ -108,7 +108,7 @@ class NorthMacedonia(
     )
     supported_languages = ("en_US", "mk", "uk")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/oman.py b/holidays/countries/oman.py
index a243aefd..4401d54b 100644
--- a/holidays/countries/oman.py
+++ b/holidays/countries/oman.py
@@ -53,7 +53,7 @@ class Oman(HolidayBase, IslamicHolidays):
     start_year = 1970
     supported_languages = ("ar", "en_US")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/pakistan.py b/holidays/countries/pakistan.py
index 1a0eaef9..554bf722 100644
--- a/holidays/countries/pakistan.py
+++ b/holidays/countries/pakistan.py
@@ -35,7 +35,7 @@ class Pakistan(HolidayBase, InternationalHolidays, IslamicHolidays):
     start_year = 1948
     supported_languages = ("en_PK", "en_US", "ur_PK")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/philippines.py b/holidays/countries/philippines.py
index bd2df610..eb5097a5 100644
--- a/holidays/countries/philippines.py
+++ b/holidays/countries/philippines.py
@@ -63,7 +63,7 @@ class Philippines(
     supported_languages = ("en_PH", "en_US", "fil", "th")
     start_year = 1988
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/qatar.py b/holidays/countries/qatar.py
index fbb0c476..d276bff9 100644
--- a/holidays/countries/qatar.py
+++ b/holidays/countries/qatar.py
@@ -52,7 +52,7 @@ class Qatar(HolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays)
     supported_categories = (BANK, PUBLIC)
     supported_languages = ("ar_QA", "en_US")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/saudi_arabia.py b/holidays/countries/saudi_arabia.py
index f2cd7da9..64559073 100644
--- a/holidays/countries/saudi_arabia.py
+++ b/holidays/countries/saudi_arabia.py
@@ -45,7 +45,7 @@ class SaudiArabia(ObservedHolidayBase, IslamicHolidays, StaticHolidays):
     observed_estimated_label = tr("(تقدير ملاحظة) %s")
     supported_languages = ("ar", "en_US")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/senegal.py b/holidays/countries/senegal.py
new file mode 100644
index 00000000..3c1f2324
--- /dev/null
+++ b/holidays/countries/senegal.py
@@ -0,0 +1,193 @@
+#  holidays
+#  --------
+#  A fast, efficient Python library for generating country, province and state
+#  specific sets of holidays on the fly. It aims to make determining whether a
+#  specific date is a holiday as fast and flexible as possible.
+#
+#  Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file)
+#           dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
+#           ryanss <ryanssdev@icloud.com> (c) 2014-2017
+#  Website: https://github.com/vacanza/holidays
+#  License: MIT (see LICENSE file)
+
+from gettext import gettext as tr
+
+from holidays.calendars import _CustomIslamicHolidays
+from holidays.calendars.gregorian import MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, DEC
+from holidays.groups import (
+    ChristianHolidays,
+    InternationalHolidays,
+    IslamicHolidays,
+    StaticHolidays,
+)
+from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON
+
+
+class Senegal(
+    ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays, StaticHolidays
+):
+    """Senegal holidays.
+    References:
+        * <https://en.wikipedia.org/wiki/Public_holidays_in_Senegal>
+        * [Law 63-51](https://web.archive.org/web/20250604134724/https://www.dri.gouv.sn/sites/default/files/LOI/1963/63_51.pdf)
+        * [Law 74-52](https://web.archive.org/web/20250608105243/https://www.dri.gouv.sn/sites/default/files/an-documents/LOI%20N1974%2052%20DU%204%20NOVEMBRE%201974.pdf)
+        * [Law 83-54](https://web.archive.org/web/20250608105419/https://www.dri.gouv.sn/sites/default/files/LOI/1983/comP4%20loi%20decentralisation%20et%20travail/LOI%20N%20198354%20DU%2018%20FEVRIER%201983/LOI%20N%20198354%20DU%2018%20FEVRIER%201983.pdf)
+        * [Law 2013-06](https://web.archive.org/web/20250604215148/https://natlex.ilo.org/dyn/natlex2/natlex2/files/download/97261/SEN-97261.pdf)
+    """
+
+    country = "SN"
+    default_language = "fr_SN"
+    # %s (estimated).
+    estimated_label = tr("%s (estimé)")
+    # %s (observed).
+    observed_label = tr("%s (observé)")
+    # %s (observed, estimated).
+    observed_estimated_label = tr("%s (observé, estimé)")
+    # First official source with holidays dates (Law 63-51).
+    start_year = 1964
+    supported_languages = ("en_US", "fr_SN")
+
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
+        """
+        Args:
+            islamic_show_estimated:
+                Whether to add "estimated" label to Islamic holidays name
+                if holiday date is estimated.
+        """
+        ChristianHolidays.__init__(self)
+        InternationalHolidays.__init__(self)
+        IslamicHolidays.__init__(
+            self, cls=SenegalIslamicHolidays, show_estimated=islamic_show_estimated
+        )
+        StaticHolidays.__init__(self, SenegalStaticHolidays)
+        # Law 74-52.
+        kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON)
+        kwargs.setdefault("observed_since", 1975)
+        super().__init__(*args, **kwargs)
+
+    def _populate_public_holidays(self):
+        if self._year >= 1983:
+            # Ashura.
+            self._add_ashura_day(tr("Tamxarit"))
+
+        if self._year >= 2014:
+            # Grand Magal of Touba.
+            self._add_grand_magal_of_touba(tr("Grand Magal de Touba"))
+
+        # Prophet's Birthday.
+        self._add_mawlid_day(tr("Journée du Maouloud"))
+
+        # Eid al-Fitr.
+        for dt in self._add_eid_al_fitr_day(tr("Journée de la Korité")):
+            self._add_observed(dt)
+
+        # Eid al-Adha.
+        for dt in self._add_eid_al_adha_day(tr("Journée de la Tabaski")):
+            self._add_observed(dt)
+
+        # New Year's Day.
+        self._add_new_years_day(tr("Jour de l'an"))
+
+        if 1983 <= self._year <= 1989:
+            # Senegambia Confederation Day.
+            self._add_holiday_feb_1(tr("Fête de la Confédération de la Sénégambie"))
+
+        # Independence Day.
+        name = tr("Fête de l'Indépendance")
+        if self._year >= 1975:
+            self._add_holiday_apr_4(name)
+        else:
+            self._add_holiday_jul_14(name)
+
+        # Easter Monday.
+        self._add_easter_monday(tr("Lundi de Pâques"))
+
+        # Labor Day.
+        self._add_labor_day(tr("Fête du Travail"))
+
+        # Ascension Day.
+        self._add_ascension_thursday(tr("Jeudi de l'Ascension"))
+
+        # Whit Monday.
+        self._add_whit_monday(tr("Lundi de Pentecôte"))
+
+        # Assumption Day.
+        self._add_assumption_of_mary_day(tr("Assomption"))
+
+        # All Saints' Day.
+        self._add_all_saints_day(tr("Toussaint"))
+
+        # Christmas Day.
+        self._add_christmas_day(tr("Noël"))
+
+
+class SN(Senegal):
+    pass
+
+
+class SEN(Senegal):
+    pass
+
+
+class SenegalIslamicHolidays(_CustomIslamicHolidays):
+    # https://web.archive.org/web/20250609044648/https://www.timeanddate.com/holidays/senegal/tamkharit
+    ASHURA_DATES = {
+        2020: (AUG, 29),
+        2021: (AUG, 18),
+        2022: (AUG, 8),
+        2023: (JUL, 28),
+        2024: (JUL, 17),
+    }
+
+    # https://web.archive.org/web/20250609061446/https://www.timeanddate.com/holidays/senegal/grand-magal-de-touba
+    GRAND_MAGAL_OF_TOUBA_DATES = {
+        2020: (OCT, 6),
+        2021: (SEP, 26),
+        2022: (SEP, 15),
+        2023: (SEP, 4),
+        2024: (AUG, 23),
+    }
+
+    # https://web.archive.org/web/20250609091559/https://www.timeanddate.com/holidays/senegal/maouloud
+    MAWLID_DATES = {
+        2020: (OCT, 29),
+        2021: (OCT, 18),
+        2022: (OCT, 8),
+        2023: (SEP, 27),
+        2024: (SEP, 15),
+    }
+
+    # https://web.archive.org/web/20250609092813/https://www.timeanddate.com/holidays/senegal/korite
+    EID_AL_FITR_DATES = {
+        2020: (MAY, 24),
+        2021: (MAY, 12),
+        2022: (MAY, 1),
+        2023: (APR, 22),
+        2024: (APR, 10),
+        2025: (MAR, 30),
+    }
+
+    # https://web.archive.org/web/20250609102658/https://www.timeanddate.com/holidays/senegal/tabaski
+    EID_AL_ADHA_DATES = {
+        2020: (JUL, 31),
+        2021: (JUL, 21),
+        2022: (JUL, 10),
+        2023: (JUN, 29),
+        2024: (JUN, 17),
+    }
+
+
+class SenegalStaticHolidays:
+    """Senegal special holidays.
+
+    References:
+        * [29th October, 2018 Public holiday](https://web.archive.org/web/20250608105852/https://www.juriafrica.com/lex/decret-2018-1942-26-octobre-2018-48947.htm)
+        * [26th December, 2022 Public holiday](https://web.archive.org/web/20250608135605/https://primature.sn/publications/conseil-des-ministres/conseil-des-ministres-du-22-decembre-2022)
+    """
+
+    # Public holiday.
+    name = tr("Jour férié")
+    special_public_holidays = {
+        2018: (OCT, 29, name),
+        2022: (DEC, 26, name),
+    }
diff --git a/holidays/countries/sierra_leone.py b/holidays/countries/sierra_leone.py
index 51db25ac..5724fd0a 100644
--- a/holidays/countries/sierra_leone.py
+++ b/holidays/countries/sierra_leone.py
@@ -40,7 +40,7 @@ class SierraLeone(ObservedHolidayBase, ChristianHolidays, InternationalHolidays,
     # Sierra Leone gained independence on April 27, 1961.
     start_year = 1962
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/singapore.py b/holidays/countries/singapore.py
index d302fbf4..2971f006 100644
--- a/holidays/countries/singapore.py
+++ b/holidays/countries/singapore.py
@@ -65,7 +65,7 @@ class Singapore(
     observed_label = tr("%s (observed)")
     supported_languages = ("en_SG", "en_US", "th")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/spain.py b/holidays/countries/spain.py
index 1899dc10..d78aa5dc 100644
--- a/holidays/countries/spain.py
+++ b/holidays/countries/spain.py
@@ -100,7 +100,7 @@ class Spain(
     }
     supported_languages = ("en_US", "es", "uk")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/sri_lanka.py b/holidays/countries/sri_lanka.py
index cc7125e8..9dd66a31 100644
--- a/holidays/countries/sri_lanka.py
+++ b/holidays/countries/sri_lanka.py
@@ -88,7 +88,7 @@ class SriLanka(
     start_year = 1972
     end_year = 2025
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/suriname.py b/holidays/countries/suriname.py
index 1a4dfdc9..01b4c85b 100644
--- a/holidays/countries/suriname.py
+++ b/holidays/countries/suriname.py
@@ -57,7 +57,7 @@ class Suriname(
     start_year = 1972
     supported_languages = ("en_US", "nl")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/tanzania.py b/holidays/countries/tanzania.py
index 321eb2dc..4d48d911 100644
--- a/holidays/countries/tanzania.py
+++ b/holidays/countries/tanzania.py
@@ -66,7 +66,7 @@ class Tanzania(
     # Written Law (Miscellaneous Amendments) (No. 2) Act, 1994.
     start_year = 1994
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/timor_leste.py b/holidays/countries/timor_leste.py
index 6dc14ee3..618b4d93 100644
--- a/holidays/countries/timor_leste.py
+++ b/holidays/countries/timor_leste.py
@@ -52,7 +52,7 @@ class TimorLeste(
     # Law No. 10/2005 Of 10 August, Public Holidays and Official Commemorative Dates.
     start_year = 2006
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/togo.py b/holidays/countries/togo.py
index 23b8956e..466d2c22 100644
--- a/holidays/countries/togo.py
+++ b/holidays/countries/togo.py
@@ -56,7 +56,7 @@ class Togo(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHoliday
     # Togo gained independence on April 27, 1960.
     start_year = 1961
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/trinidad_and_tobago.py b/holidays/countries/trinidad_and_tobago.py
index 8b144441..026b8987 100644
--- a/holidays/countries/trinidad_and_tobago.py
+++ b/holidays/countries/trinidad_and_tobago.py
@@ -67,7 +67,7 @@ class TrinidadAndTobago(
     # Trinidad and Tobago gained independence on August 31, 1962.
     start_year = 1963
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
@@ -98,10 +98,10 @@ class TrinidadAndTobago(
         dts_observed.add(self._add_new_years_day(tr("New Year's Day")))
 
         # Good Friday.
-        dts_observed.add(self._add_good_friday(tr("Good Friday")))
+        self._add_good_friday(tr("Good Friday"))
 
         # Easter Monday.
-        dts_observed.add(self._add_easter_monday(tr("Easter Monday")))
+        self._add_easter_monday(tr("Easter Monday"))
 
         if self._year >= 1996:
             # Spiritual Baptist Liberation Day.
diff --git a/holidays/countries/tunisia.py b/holidays/countries/tunisia.py
index 18f6e903..32d9ee9e 100644
--- a/holidays/countries/tunisia.py
+++ b/holidays/countries/tunisia.py
@@ -25,7 +25,7 @@ class Tunisia(HolidayBase, InternationalHolidays, IslamicHolidays):
     estimated_label = tr("(تقدير) %s")
     supported_languages = ("ar", "en_US")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/turkey.py b/holidays/countries/turkey.py
index ae1607d1..b9b9a043 100644
--- a/holidays/countries/turkey.py
+++ b/holidays/countries/turkey.py
@@ -38,7 +38,7 @@ class Turkey(HolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays
     # Law 2739 of 27 May 1935.
     start_year = 1936
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/united_arab_emirates.py b/holidays/countries/united_arab_emirates.py
index 8fc29c62..a9956692 100644
--- a/holidays/countries/united_arab_emirates.py
+++ b/holidays/countries/united_arab_emirates.py
@@ -66,7 +66,7 @@ class UnitedArabEmirates(HolidayBase, InternationalHolidays, IslamicHolidays, St
     # Founded on DEC 2, 1971.
     start_year = 1972
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/uzbekistan.py b/holidays/countries/uzbekistan.py
index 85385cb1..988d5887 100644
--- a/holidays/countries/uzbekistan.py
+++ b/holidays/countries/uzbekistan.py
@@ -39,7 +39,7 @@ class Uzbekistan(ObservedHolidayBase, InternationalHolidays, IslamicHolidays, St
     supported_languages = ("en_US", "uk", "uz")
     start_year = 1992
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/countries/yemen.py b/holidays/countries/yemen.py
index 1f7eec21..1c762f90 100644
--- a/holidays/countries/yemen.py
+++ b/holidays/countries/yemen.py
@@ -61,7 +61,7 @@ class Yemen(ObservedHolidayBase, InternationalHolidays, IslamicHolidays):
     supported_categories = (PUBLIC, SCHOOL, WORKDAY)
     supported_languages = ("ar", "en_US")
 
-    def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs):
+    def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
         """
         Args:
             islamic_show_estimated:
diff --git a/holidays/groups/islamic.py b/holidays/groups/islamic.py
index 825f44f7..6f788a9e 100644
--- a/holidays/groups/islamic.py
+++ b/holidays/groups/islamic.py
@@ -222,6 +222,16 @@ class IslamicHolidays(EasternCalendarHolidays):
             name, self._islamic_calendar.fatima_death_dates(self._year)
         )
 
+    def _add_grand_magal_of_touba(self, name) -> set[date]:
+        """
+        Annual religious pilgrimage of Senegalese Mouride brotherhood.
+
+        https://en.wikipedia.org/wiki/Grand_Magal_of_Touba
+        """
+        return self._add_islamic_calendar_holiday(
+            name, self._islamic_calendar.grand_magal_of_touba_dates(self._year)
+        )
+
     def _add_hari_hol_johor(self, name) -> set[date]:
         """
         Hari Hol Johor.
diff --git a/holidays/locale/en_US/LC_MESSAGES/SN.po b/holidays/locale/en_US/LC_MESSAGES/SN.po
new file mode 100644
index 00000000..69606614
--- /dev/null
+++ b/holidays/locale/en_US/LC_MESSAGES/SN.po
@@ -0,0 +1,107 @@
+#  holidays
+#  --------
+#  A fast, efficient Python library for generating country, province and state
+#  specific sets of holidays on the fly. It aims to make determining whether a
+#  specific date is a holiday as fast and flexible as possible.
+#
+#  Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file)
+#           dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
+#           ryanss <ryanssdev@icloud.com> (c) 2014-2017
+#  Website: https://github.com/vacanza/holidays
+#  License: MIT (see LICENSE file)
+#
+# Senegal holidays en_US localization.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Holidays 0.75\n"
+"POT-Creation-Date: 2025-06-04 11:37+0500\n"
+"PO-Revision-Date: 2025-06-04 11:40+0500\n"
+"Last-Translator: Wasif Shahzad <wasif_shahzad_1@outlook.com>\n"
+"Language-Team: Holidays Localization Team\n"
+"Language: en_US\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Lingva 5.0.6\n"
+"X-Generator: Poedit 3.6\n"
+"X-Source-Language: fr_SN\n"
+
+#. %s (estimated).
+#, c-format
+msgid "%s (estimé)"
+msgstr "%s (estimated)"
+
+#. New Year's Day.
+msgid "Jour de l'an"
+msgstr "New Year's Day"
+
+#. Independence Day.
+msgid "Fête de l'Indépendance"
+msgstr "Independence Day"
+
+#. Labor Day.
+msgid "Fête du Travail"
+msgstr "Labor Day"
+
+#. Assumption Day.
+msgid "Assomption"
+msgstr "Assumption Day"
+
+#. All Saints' Day.
+msgid "Toussaint"
+msgstr "All Saints' Day"
+
+#. Christmas Day.
+msgid "Noël"
+msgstr "Christmas Day"
+
+#. Easter Monday.
+msgid "Lundi de Pâques"
+msgstr "Easter Monday"
+
+#. Whit Monday.
+msgid "Lundi de Pentecôte"
+msgstr "Whit Monday"
+
+#. Grand Magal of Touba.
+msgid "Grand Magal de Touba"
+msgstr "Grand Magal of Touba"
+
+#. %s (observed).
+#, c-format
+msgid "%s (observé)"
+msgstr "%s (observed)"
+
+#. %s (observed, estimated).
+#, c-format
+msgid "%s (observé, estimé)"
+msgstr "%s (observed, estimated)"
+
+#. Public holiday.
+msgid "Jour férié"
+msgstr "Public holiday"
+
+#. Ashura.
+msgid "Tamxarit"
+msgstr "Ashura"
+
+#. Prophet's Birthday.
+msgid "Journée du Maouloud"
+msgstr "Prophet's Birthday"
+
+#. Eid al-Fitr.
+msgid "Journée de la Korité"
+msgstr "Eid al-Fitr"
+
+#. Eid al-Adha.
+msgid "Journée de la Tabaski"
+msgstr "Eid al-Adha"
+
+#. Ascension Day.
+msgid "Jeudi de l'Ascension"
+msgstr "Ascension Day"
+
+#. Senegambia Confederation Day.
+msgid "Fête de la Confédération de la Sénégambie"
+msgstr "Senegambia Confederation Day"
diff --git a/holidays/locale/fr_SN/LC_MESSAGES/SN.po b/holidays/locale/fr_SN/LC_MESSAGES/SN.po
new file mode 100644
index 00000000..f589ede3
--- /dev/null
+++ b/holidays/locale/fr_SN/LC_MESSAGES/SN.po
@@ -0,0 +1,106 @@
+#  holidays
+#  --------
+#  A fast, efficient Python library for generating country, province and state
+#  specific sets of holidays on the fly. It aims to make determining whether a
+#  specific date is a holiday as fast and flexible as possible.
+#
+#  Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file)
+#           dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
+#           ryanss <ryanssdev@icloud.com> (c) 2014-2017
+#  Website: https://github.com/vacanza/holidays
+#  License: MIT (see LICENSE file)
+#
+# Senegal holidays.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Holidays 0.75\n"
+"POT-Creation-Date: 2025-06-04 16:10+0500\n"
+"PO-Revision-Date: 2025-06-04 16:10+0500\n"
+"Last-Translator: Wasif Shahzad <wasif_shahzad_1@outlook.com>\n"
+"Language-Team: Holidays Localization Team\n"
+"Language: fr_SN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Lingva 5.0.6\n"
+"X-Source-Language: fr_SN\n"
+
+#. %s (estimated).
+#, c-format
+msgid "%s (estimé)"
+msgstr ""
+
+#. New Year's Day.
+msgid "Jour de l'an"
+msgstr ""
+
+#. Independence Day.
+msgid "Fête de l'Indépendance"
+msgstr ""
+
+#. Labor Day.
+msgid "Fête du Travail"
+msgstr ""
+
+#. Assumption Day.
+msgid "Assomption"
+msgstr ""
+
+#. All Saints' Day.
+msgid "Toussaint"
+msgstr ""
+
+#. Christmas Day.
+msgid "Noël"
+msgstr ""
+
+#. Easter Monday.
+msgid "Lundi de Pâques"
+msgstr ""
+
+#. Whit Monday.
+msgid "Lundi de Pentecôte"
+msgstr ""
+
+#. Grand Magal of Touba.
+msgid "Grand Magal de Touba"
+msgstr ""
+
+#. %s (observed).
+#, c-format
+msgid "%s (observé)"
+msgstr ""
+
+#. %s (observed, estimated).
+#, c-format
+msgid "%s (observé, estimé)"
+msgstr ""
+
+#. Public holiday.
+msgid "Jour férié"
+msgstr ""
+
+#. Ashura.
+msgid "Tamxarit"
+msgstr ""
+
+#. Prophet's Birthday.
+msgid "Journée du Maouloud"
+msgstr ""
+
+#. Eid al-Fitr.
+msgid "Journée de la Korité"
+msgstr ""
+
+#. Eid al-Adha.
+msgid "Journée de la Tabaski"
+msgstr ""
+
+#. Ascension Day.
+msgid "Jeudi de l'Ascension"
+msgstr ""
+
+#. Senegambia Confederation Day.
+msgid "Fête de la Confédération de la Sénégambie"
+msgstr ""
diff --git a/holidays/registry.py b/holidays/registry.py
index 2df0e50c..e263c7f7 100644
--- a/holidays/registry.py
+++ b/holidays/registry.py
@@ -166,6 +166,7 @@ COUNTRIES: RegistryDict = {
     "san_marino": ("SanMarino", "SM", "SMR"),
     "sao_tome_and_principe": ("SaoTomeAndPrincipe", "ST", "STP"),
     "saudi_arabia": ("SaudiArabia", "SA", "SAU"),
+    "senegal": ("Senegal", "SN", "SEN"),
     "serbia": ("Serbia", "RS", "SRB"),
     "seychelles": ("Seychelles", "SC", "SYC"),
     "sierra_leone": ("SierraLeone", "SL", "SLE"),
diff --git a/requirements/dev.txt b/requirements/dev.txt
index 135c8feb..aab83f0a 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -7,7 +7,7 @@ hijridate==2.5.0
 lingva==5.0.6
 pre-commit==4.2.0
 pygithub==2.6.1
-requests==2.32.3
+requests==2.32.4
 ruff==0.11.12
 tox==4.26.0
 urllib3>=2.2.2 # not directly required, pinned by Snyk to avoid a vulnerability
diff --git a/scripts/calendar/islamic_generator.py b/scripts/calendar/islamic_generator.py
index 8e52cdb5..726a97b6 100644
--- a/scripts/calendar/islamic_generator.py
+++ b/scripts/calendar/islamic_generator.py
@@ -38,6 +38,8 @@ ISLAMIC_HOLIDAYS = (
     (1, 10, "ASHURA"),  # Ashura
     # MY
     (2, 6, "HARI_HOL_JOHOR"),  # Hari Hol of Johor
+    # SN
+    (2, 18, "GRAND_MAGAL_OF_TOUBA"),  # Grand Magal of Touba
     # BH, DJ, EG, ET, IN, ID, MY, MA, NG, PK, TN, AE
     (3, 12, "MAWLID"),  # Birthday of Prophet
     # DJ, ID, IR, MY, AE
diff --git a/scripts/l10n/l10n_helper.py b/scripts/l10n/l10n_helper.py
new file mode 100644
index 00000000..940163b1
--- /dev/null
+++ b/scripts/l10n/l10n_helper.py
@@ -0,0 +1,235 @@
+#!/usr/bin/env python3
+
+
+#  holidays
+#  --------
+#  A fast, efficient Python library for generating country, province and state
+#  specific sets of holidays on the fly. It aims to make determining whether a
+#  specific date is a holiday as fast and flexible as possible.
+#
+#  Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file)
+#           dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
+#           ryanss <ryanssdev@icloud.com> (c) 2014-2017
+#  Website: https://github.com/vacanza/holidays
+#  License: MIT (see LICENSE file)
+
+# ruff: noqa: T201
+
+import argparse
+import csv
+import importlib
+import sys
+from collections import defaultdict
+from pathlib import Path
+
+from polib import pofile
+
+WRAP_WIDTH = 99
+
+
+class LocalizationHelper:
+    def __init__(self) -> None:
+        arg_parser = argparse.ArgumentParser()
+        arg_parser.add_argument("country_code", help="Country code", type=str)
+        arg_parser.add_argument("--create-po", action="store_true", help="Create .po files")
+        arg_parser.add_argument("--export-csv", action="store_true", help="Export to .csv")
+        arg_parser.add_argument("--import-csv", action="store_true", help="Import from .csv")
+        arg_parser.add_argument(
+            "--fill-missing",
+            action="store_true",
+            help="Fill missing translations from other countries",
+        )
+        arg_parser.add_argument(
+            "--bom",
+            action=argparse.BooleanOptionalAction,
+            default=False,
+            help="Use files with BOM on export/import",
+        )
+        arg_parser.add_argument(
+            "--overwrite",
+            action=argparse.BooleanOptionalAction,
+            default=False,
+            help="Overwrite existing files",
+        )
+        self.args = arg_parser.parse_args()
+        if not any(
+            getattr(self.args, action.dest)
+            for action in arg_parser._actions
+            if isinstance(action, argparse._StoreTrueAction)
+        ):
+            print("No action specified.\n")
+            arg_parser.print_help()
+            sys.exit(1)
+
+        self.country_code = self.args.country_code
+        self.encoding = "utf-8-sig" if self.args.bom else "utf-8"
+        self.csv_file_path = Path(f"holidays/locale/csv/{self.country_code}.csv")
+
+    def create_po_files(self):
+        sys.path.append(str(Path.cwd()))  # Make holidays visible.
+        from holidays.registry import COUNTRIES
+
+        class_name = None
+        for module_name, entity_data in COUNTRIES.items():
+            if entity_data[1] == self.country_code:
+                class_name = entity_data[0]
+                break
+        if not class_name:
+            print(f"Class for country code {self.country_code} not found!")
+            sys.exit(1)
+
+        cls = getattr(importlib.import_module(f"holidays.countries.{module_name}"), class_name)
+        docstring = cls.__doc__
+
+        header = [
+            f"# {line}" if line else "#"
+            for line in Path("docs/file_header.txt").read_text(encoding="utf-8").split("\n")
+        ]
+        country_name = "COUNTRY"
+        if (title := docstring.split("\n")[0]) and title.endswith(" holidays."):
+            country_name = title.split("holidays")[0].strip()
+
+        locale_directory = Path("holidays/locale")
+        pot_file_path = locale_directory / "pot" / f"{self.country_code}.pot"
+        pot_file = pofile(pot_file_path, wrapwidth=WRAP_WIDTH)
+
+        for language in cls.supported_languages:
+            po_directory = locale_directory / language / "LC_MESSAGES"
+            po_directory.mkdir(parents=True, exist_ok=True)
+            po_file_path = po_directory / f"{self.country_code}.po"
+            if not self.args.overwrite and po_file_path.exists():
+                continue
+            pot_file.metadata["Language"] = language
+            pot_file.save(po_file_path, newline="\n")
+
+            file_content = po_file_path.read_text(encoding="utf-8").split("\n")
+            if file_content[0] != "# SOME DESCRIPTIVE TITLE":
+                continue
+            l10n_suffix = f" {language} localization" if language != cls.default_language else ""
+            title = f"# {country_name} holidays{l10n_suffix}."
+            file_content = header + [title, "#"] + file_content[4:]
+            po_file_path.write_text("\n".join(file_content), encoding="utf-8", newline="\n")
+
+        en_us_po_path = locale_directory / "en_us/LC_MESSAGES" / f"{self.country_code}.po"
+        po_file = pofile(en_us_po_path, wrapwidth=WRAP_WIDTH)
+        for po_entry in po_file:
+            if po_entry.comment:
+                po_entry.msgstr = po_entry.comment.removesuffix(".")
+        po_file.save(en_us_po_path, newline="\n")
+
+    def export_to_csv(self):
+        if not self.args.overwrite and self.csv_file_path.exists():
+            print(f"File {self.csv_file_path} exists and no --overwrite option!")
+            sys.exit(1)
+
+        comments = {}
+        languages = []
+        po_data = defaultdict(dict)
+        for po_path in Path("holidays/locale").rglob(f"{self.country_code}.po"):
+            po_file = pofile(po_path, wrapwidth=WRAP_WIDTH)
+            language = po_file.metadata["Language"]
+            default_language = po_file.metadata["X-Source-Language"]
+            if language != default_language:
+                languages.append(language)
+                for po_entry in po_file:
+                    po_data[po_entry.msgid][language] = po_entry.msgstr
+            else:
+                for po_entry in po_file:
+                    comments[po_entry.msgid] = po_entry.comment
+
+        languages = sorted(languages)
+        headers = ["msgid", "msgcomment", *languages]
+        rows = [
+            [msgid, comments[msgid]] + [po_data[msgid][language] for language in languages]
+            for msgid in po_data
+        ]
+        self.write_csv(headers, rows)
+
+    def read_csv(self) -> tuple[list[str], list[list[str]]]:
+        if not self.csv_file_path.exists():
+            print(f"File {self.csv_file_path} not found!")
+            sys.exit(1)
+
+        with self.csv_file_path.open("r", encoding=self.encoding) as f:
+            reader = csv.reader(f, delimiter=";")
+            headers, *rows = reader
+        return headers, rows
+
+    def write_csv(self, headers: list[str], rows: list[list[str]]):
+        self.csv_file_path.parent.mkdir(parents=True, exist_ok=True)
+        with self.csv_file_path.open("w", newline="", encoding=self.encoding) as f:
+            writer = csv.writer(f, delimiter=";")
+            writer.writerow(headers)
+            writer.writerows(rows)
+
+    def import_from_csv(self):
+        headers, rows = self.read_csv()
+        languages = headers[2:]
+        entries = [(msgid, dict(zip(languages, msgstrs))) for msgid, _, *msgstrs in rows]
+
+        for language in languages:
+            po_path = Path(f"holidays/locale/{language}/LC_MESSAGES/{self.country_code}.po")
+            po_file = pofile(po_path, wrapwidth=WRAP_WIDTH)
+
+            changed = False
+            for msgid, msg_mapping in entries:
+                entry = po_file.find(msgid)
+                if not entry:
+                    continue
+                msgstr = msg_mapping[language]
+                if entry.msgstr != msgstr:
+                    entry.msgstr = msgstr
+                    changed = True
+
+            if changed:
+                po_file.save(po_path, newline="\n")
+
+    def fill_missing_translations(self):
+        headers, rows = self.read_csv()
+        languages = headers[2:]
+
+        untranslated_languages = set()
+        for row in rows:
+            msgstrs = row[2:]
+            for lang, msgstr in zip(languages, msgstrs):
+                if not msgstr.strip():
+                    untranslated_languages.add(lang)
+
+        translations = defaultdict(lambda: defaultdict(set))
+        for language in untranslated_languages:
+            for po_path in Path(f"holidays/locale/{language}/LC_MESSAGES/").glob("*.po"):
+                if po_path.stem == self.country_code:
+                    continue
+                po_file = pofile(po_path, wrapwidth=WRAP_WIDTH)
+                for entry in po_file:
+                    if entry.comment and entry.msgstr:
+                        translations[language][entry.comment].add(entry.msgstr)
+
+        updated_rows = []
+        for msgid, msgcomment, *msgstrs in rows:
+            new_msgstrs = []
+            for lang, msgstr in zip(languages, msgstrs):
+                if msgstr.strip():
+                    new_msgstrs.append(msgstr)
+                elif msgcomment in translations[lang]:
+                    new_msgstrs.append("/".join(sorted(translations[lang][msgcomment])))
+                else:
+                    new_msgstrs.append("")
+
+            updated_rows.append([msgid, msgcomment, *new_msgstrs])
+
+        self.write_csv(headers, updated_rows)
+
+    def run(self):
+        if self.args.create_po:
+            self.create_po_files()
+        elif self.args.export_csv:
+            self.export_to_csv()
+        elif self.args.import_csv:
+            self.import_from_csv()
+        elif self.args.fill_missing:
+            self.fill_missing_translations()
+
+
+if __name__ == "__main__":
+    LocalizationHelper().run()
diff --git a/snapshots/countries/HU_COMMON.json b/snapshots/countries/HU_COMMON.json
index 7006136f..71498d5f 100644
--- a/snapshots/countries/HU_COMMON.json
+++ b/snapshots/countries/HU_COMMON.json
@@ -457,6 +457,7 @@
     "1991-04-01": "Easter Monday",
     "1991-05-01": "Labor Day",
     "1991-05-19": "Whit Sunday",
+    "1991-08-19": "Day off (substituted from 08/17/1991)",
     "1991-08-20": "State Foundation Day",
     "1991-10-23": "National Day",
     "1991-12-25": "Christmas Day",
@@ -469,7 +470,9 @@
     "1992-06-07": "Whit Sunday",
     "1992-06-08": "Whit Monday",
     "1992-08-20": "State Foundation Day",
+    "1992-08-21": "Day off (substituted from 08/29/1992)",
     "1992-10-23": "National Day",
+    "1992-12-24": "Day off (substituted from 12/19/1992)",
     "1992-12-25": "Christmas Day",
     "1992-12-26": "Second Day of Christmas",
     "1993-01-01": "New Year's Day",
@@ -481,9 +484,11 @@
     "1993-05-31": "Whit Monday",
     "1993-08-20": "State Foundation Day",
     "1993-10-23": "National Day",
+    "1993-12-24": "Day off (substituted from 12/18/1993)",
     "1993-12-25": "Christmas Day",
     "1993-12-26": "Second Day of Christmas",
     "1994-01-01": "New Year's Day",
+    "1994-03-14": "Day off (substituted from 03/12/1994)",
     "1994-03-15": "National Day",
     "1994-04-03": "Easter",
     "1994-04-04": "Easter Monday",
@@ -521,13 +526,17 @@
     "1997-03-30": "Easter",
     "1997-03-31": "Easter Monday",
     "1997-05-01": "Labor Day",
+    "1997-05-02": "Day off (substituted from 04/26/1997)",
     "1997-05-18": "Whit Sunday",
     "1997-05-19": "Whit Monday",
     "1997-08-20": "State Foundation Day",
     "1997-10-23": "National Day",
+    "1997-10-24": "Day off (substituted from 10/18/1997)",
+    "1997-12-24": "Day off (substituted from 12/20/1997)",
     "1997-12-25": "Christmas Day",
     "1997-12-26": "Second Day of Christmas",
     "1998-01-01": "New Year's Day",
+    "1998-01-02": "Day off (substituted from 01/10/1998)",
     "1998-03-15": "National Day",
     "1998-04-12": "Easter",
     "1998-04-13": "Easter Monday",
@@ -535,7 +544,9 @@
     "1998-05-31": "Whit Sunday",
     "1998-06-01": "Whit Monday",
     "1998-08-20": "State Foundation Day",
+    "1998-08-21": "Day off (substituted from 08/15/1998)",
     "1998-10-23": "National Day",
+    "1998-12-24": "Day off (substituted from 12/19/1998)",
     "1998-12-25": "Christmas Day",
     "1998-12-26": "Second Day of Christmas",
     "1999-01-01": "New Year's Day",
@@ -548,6 +559,7 @@
     "1999-08-20": "State Foundation Day",
     "1999-10-23": "National Day",
     "1999-11-01": "All Saints' Day",
+    "1999-12-24": "Day off (substituted from 12/18/1999)",
     "1999-12-25": "Christmas Day",
     "1999-12-26": "Second Day of Christmas",
     "2000-01-01": "New Year's Day",
@@ -564,16 +576,22 @@
     "2000-12-26": "Second Day of Christmas",
     "2001-01-01": "New Year's Day",
     "2001-03-15": "National Day",
+    "2001-03-16": "Day off (substituted from 03/10/2001)",
     "2001-04-15": "Easter",
     "2001-04-16": "Easter Monday",
+    "2001-04-30": "Day off (substituted from 04/28/2001)",
     "2001-05-01": "Labor Day",
     "2001-06-03": "Whit Sunday",
     "2001-06-04": "Whit Monday",
     "2001-08-20": "State Foundation Day",
+    "2001-10-22": "Day off (substituted from 10/20/2001)",
     "2001-10-23": "National Day",
     "2001-11-01": "All Saints' Day",
+    "2001-11-02": "Day off (substituted from 10/27/2001)",
+    "2001-12-24": "Day off (substituted from 12/22/2001)",
     "2001-12-25": "Christmas Day",
     "2001-12-26": "Second Day of Christmas",
+    "2001-12-31": "Day off (substituted from 12/29/2001)",
     "2002-01-01": "New Year's Day",
     "2002-03-15": "National Day",
     "2002-03-31": "Easter",
@@ -581,9 +599,11 @@
     "2002-05-01": "Labor Day",
     "2002-05-19": "Whit Sunday",
     "2002-05-20": "Whit Monday",
+    "2002-08-19": "Day off (substituted from 08/10/2002)",
     "2002-08-20": "State Foundation Day",
     "2002-10-23": "National Day",
     "2002-11-01": "All Saints' Day",
+    "2002-12-24": "Day off (substituted from 12/28/2002)",
     "2002-12-25": "Christmas Day",
     "2002-12-26": "Second Day of Christmas",
     "2003-01-01": "New Year's Day",
@@ -591,14 +611,18 @@
     "2003-04-20": "Easter",
     "2003-04-21": "Easter Monday",
     "2003-05-01": "Labor Day",
+    "2003-05-02": "Day off (substituted from 04/26/2003)",
     "2003-06-08": "Whit Sunday",
     "2003-06-09": "Whit Monday",
     "2003-08-20": "State Foundation Day",
     "2003-10-23": "National Day",
+    "2003-10-24": "Day off (substituted from 10/18/2003)",
     "2003-11-01": "All Saints' Day",
+    "2003-12-24": "Day off (substituted from 12/13/2003)",
     "2003-12-25": "Christmas Day",
     "2003-12-26": "Second Day of Christmas",
     "2004-01-01": "New Year's Day",
+    "2004-01-02": "Day off (substituted from 01/10/2004)",
     "2004-03-15": "National Day",
     "2004-04-11": "Easter",
     "2004-04-12": "Easter Monday",
@@ -608,9 +632,11 @@
     "2004-08-20": "State Foundation Day",
     "2004-10-23": "National Day",
     "2004-11-01": "All Saints' Day",
+    "2004-12-24": "Day off (substituted from 12/18/2004)",
     "2004-12-25": "Christmas Day",
     "2004-12-26": "Second Day of Christmas",
     "2005-01-01": "New Year's Day",
+    "2005-03-14": "Day off (substituted from 03/19/2005)",
     "2005-03-15": "National Day",
     "2005-03-27": "Easter",
     "2005-03-28": "Easter Monday",
@@ -619,6 +645,7 @@
     "2005-05-16": "Whit Monday",
     "2005-08-20": "State Foundation Day",
     "2005-10-23": "National Day",
+    "2005-10-31": "Day off (substituted from 11/05/2005)",
     "2005-11-01": "All Saints' Day",
     "2005-12-25": "Christmas Day",
     "2005-12-26": "Second Day of Christmas",
@@ -636,29 +663,39 @@
     "2006-12-26": "Second Day of Christmas",
     "2007-01-01": "New Year's Day",
     "2007-03-15": "National Day",
+    "2007-03-16": "Day off (substituted from 03/10/2007)",
     "2007-04-08": "Easter",
     "2007-04-09": "Easter Monday",
+    "2007-04-30": "Day off (substituted from 04/21/2007)",
     "2007-05-01": "Labor Day",
     "2007-05-27": "Whit Sunday",
     "2007-05-28": "Whit Monday",
     "2007-08-20": "State Foundation Day",
+    "2007-10-22": "Day off (substituted from 10/20/2007)",
     "2007-10-23": "National Day",
     "2007-11-01": "All Saints' Day",
+    "2007-11-02": "Day off (substituted from 10/27/2007)",
+    "2007-12-24": "Day off (substituted from 12/22/2007)",
     "2007-12-25": "Christmas Day",
     "2007-12-26": "Second Day of Christmas",
+    "2007-12-31": "Day off (substituted from 12/29/2007)",
     "2008-01-01": "New Year's Day",
     "2008-03-15": "National Day",
     "2008-03-23": "Easter",
     "2008-03-24": "Easter Monday",
     "2008-05-01": "Labor Day",
+    "2008-05-02": "Day off (substituted from 04/26/2008)",
     "2008-05-11": "Whit Sunday",
     "2008-05-12": "Whit Monday",
     "2008-08-20": "State Foundation Day",
     "2008-10-23": "National Day",
+    "2008-10-24": "Day off (substituted from 10/18/2008)",
     "2008-11-01": "All Saints' Day",
+    "2008-12-24": "Day off (substituted from 12/20/2008)",
     "2008-12-25": "Christmas Day",
     "2008-12-26": "Second Day of Christmas",
     "2009-01-01": "New Year's Day",
+    "2009-01-02": "Day off (substituted from 03/28/2009)",
     "2009-03-15": "National Day",
     "2009-04-12": "Easter",
     "2009-04-13": "Easter Monday",
@@ -666,8 +703,10 @@
     "2009-05-31": "Whit Sunday",
     "2009-06-01": "Whit Monday",
     "2009-08-20": "State Foundation Day",
+    "2009-08-21": "Day off (substituted from 08/29/2009)",
     "2009-10-23": "National Day",
     "2009-11-01": "All Saints' Day",
+    "2009-12-24": "Day off (substituted from 12/19/2009)",
     "2009-12-25": "Christmas Day",
     "2009-12-26": "Second Day of Christmas",
     "2010-01-01": "New Year's Day",
@@ -912,6 +951,7 @@
     "2025-12-25": "Christmas Day",
     "2025-12-26": "Second Day of Christmas",
     "2026-01-01": "New Year's Day",
+    "2026-01-02": "Day off (substituted from 01/10/2026)",
     "2026-03-15": "National Day",
     "2026-04-03": "Good Friday",
     "2026-04-05": "Easter",
@@ -920,8 +960,10 @@
     "2026-05-24": "Whit Sunday",
     "2026-05-25": "Whit Monday",
     "2026-08-20": "State Foundation Day",
+    "2026-08-21": "Day off (substituted from 08/08/2026)",
     "2026-10-23": "National Day",
     "2026-11-01": "All Saints' Day",
+    "2026-12-24": "Day off (substituted from 12/12/2026)",
     "2026-12-25": "Christmas Day",
     "2026-12-26": "Second Day of Christmas",
     "2027-01-01": "New Year's Day",


Test patch:
diff --git a/tests/countries/test_hungary.py b/tests/countries/test_hungary.py
index 0f924288..22429d1c 100644
--- a/tests/countries/test_hungary.py
+++ b/tests/countries/test_hungary.py
@@ -184,6 +184,45 @@ class TestHungary(CommonCountryTests, TestCase):
 
     def test_substituted(self):
         dt = (
+            "1991-08-19",
+            "1992-08-21",
+            "1992-12-24",
+            "1993-12-24",
+            "1994-03-14",
+            "1997-05-02",
+            "1997-10-24",
+            "1997-12-24",
+            "1998-01-02",
+            "1998-08-21",
+            "1998-12-24",
+            "1999-12-24",
+            "2001-03-16",
+            "2001-04-30",
+            "2001-10-22",
+            "2001-11-02",
+            "2001-12-24",
+            "2001-12-31",
+            "2002-08-19",
+            "2002-12-24",
+            "2003-05-02",
+            "2003-10-24",
+            "2003-12-24",
+            "2004-01-02",
+            "2004-12-24",
+            "2005-03-14",
+            "2005-10-31",
+            "2007-03-16",
+            "2007-04-30",
+            "2007-10-22",
+            "2007-11-02",
+            "2007-12-24",
+            "2007-12-31",
+            "2008-05-02",
+            "2008-10-24",
+            "2008-12-24",
+            "2009-01-02",
+            "2009-08-21",
+            "2009-12-24",
             "2010-12-24",
             "2011-03-14",
             "2011-10-31",
@@ -224,6 +263,9 @@ class TestHungary(CommonCountryTests, TestCase):
             "2025-05-02",
             "2025-10-24",
             "2025-12-24",
+            "2026-01-02",
+            "2026-08-21",
+            "2026-12-24",
         )
         self.assertHoliday(dt)
 
diff --git a/tests/countries/test_senegal.py b/tests/countries/test_senegal.py
new file mode 100644
index 00000000..1e31dcf8
--- /dev/null
+++ b/tests/countries/test_senegal.py
@@ -0,0 +1,213 @@
+#  holidays
+#  --------
+#  A fast, efficient Python library for generating country, province and state
+#  specific sets of holidays on the fly. It aims to make determining whether a
+#  specific date is a holiday as fast and flexible as possible.
+#
+#  Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file)
+#           dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
+#           ryanss <ryanssdev@icloud.com> (c) 2014-2017
+#  Website: https://github.com/vacanza/holidays
+#  License: MIT (see LICENSE file)
+
+from unittest import TestCase
+
+from holidays.countries.senegal import Senegal, SN, SEN
+from tests.common import CommonCountryTests
+
+
+class TestSenegal(CommonCountryTests, TestCase):
+    @classmethod
+    def setUpClass(cls):
+        years = range(1964, 2050)
+        super().setUpClass(Senegal, years=years, years_non_observed=years)
+        cls.no_estimated_holidays = Senegal(years=years, islamic_show_estimated=False)
+
+    def test_country_aliases(self):
+        self.assertAliases(Senegal, SN, SEN)
+
+    def test_no_holidays(self):
+        self.assertNoHolidays(Senegal(years=1963))
+
+    def test_special_holidays(self):
+        self.assertHoliday(
+            "2018-10-29",
+            "2022-12-26",
+        )
+
+    def test_new_years_day(self):
+        self.assertHolidayName("Jour de l'an", (f"{year}-01-01" for year in range(1964, 2050)))
+
+    def test_confederation_day(self):
+        name = "Fête de la Confédération de la Sénégambie"
+        self.assertHolidayName(name, (f"{year}-02-01" for year in range(1983, 1990)))
+        self.assertNoHolidayName(name, range(1964, 1983), range(1990, 2050))
+
+    def test_independence_day(self):
+        self.assertHolidayName(
+            "Fête de l'Indépendance",
+            (f"{year}-07-14" for year in range(1964, 1975)),
+            (f"{year}-04-04" for year in range(1975, 2050)),
+        )
+
+    def test_labor_day(self):
+        self.assertHolidayName("Fête du Travail", (f"{year}-05-01" for year in range(1964, 2050)))
+
+    def test_assumption_of_mary_day(self):
+        self.assertHolidayName("Assomption", (f"{year}-08-15" for year in range(1964, 2050)))
+
+    def test_all_saints_day(self):
+        self.assertHolidayName("Toussaint", (f"{year}-11-01" for year in range(1964, 2050)))
+
+    def test_christmas_day(self):
+        self.assertHolidayName("Noël", (f"{year}-12-25" for year in range(1964, 2050)))
+
+    def test_easter_monday(self):
+        name = "Lundi de Pâques"
+        dts = (
+            "2020-04-13",
+            "2021-04-05",
+            "2022-04-18",
+            "2023-04-10",
+            "2024-04-01",
+        )
+        self.assertHolidayName(name, dts)
+        self.assertHolidayName(name, range(1964, 2050))
+
+    def test_ascension_day(self):
+        name = "Jeudi de l'Ascension"
+        dts = (
+            "2020-05-21",
+            "2021-05-13",
+            "2022-05-26",
+            "2023-05-18",
+            "2024-05-09",
+        )
+        self.assertHolidayName(name, dts)
+        self.assertHolidayName(name, range(1964, 2050))
+
+    def test_whit_monday(self):
+        name = "Lundi de Pentecôte"
+        dts = (
+            "2020-06-01",
+            "2021-05-24",
+            "2022-06-06",
+            "2023-05-29",
+            "2024-05-20",
+        )
+        self.assertHolidayName(name, dts)
+        self.assertHolidayName(name, range(1964, 2050))
+
+    def test_ashura(self):
+        name = "Tamxarit"
+        dts = (
+            "2020-08-29",
+            "2021-08-18",
+            "2022-08-08",
+            "2023-07-28",
+            "2024-07-17",
+        )
+        self.assertHolidayName(name, dts)
+        self.assertHolidayName(name, self.no_estimated_holidays, range(1983, 2050))
+        self.assertNoHolidayName(name, self.no_estimated_holidays, range(1964, 1983))
+
+    def test_grand_magal_of_touba(self):
+        name = "Grand Magal de Touba"
+        dts = (
+            "2020-10-06",
+            "2021-09-26",
+            "2022-09-15",
+            "2023-09-04",
+            "2024-08-23",
+        )
+        self.assertHolidayName(name, dts)
+        self.assertHolidayName(name, self.no_estimated_holidays, range(2014, 2050))
+        self.assertNoHolidayName(name, self.no_estimated_holidays, range(1964, 2014))
+
+    def test_mawlid_day(self):
+        name = "Journée du Maouloud"
+        dts = (
+            "2020-10-29",
+            "2021-10-18",
+            "2022-10-08",
+            "2023-09-27",
+            "2024-09-15",
+        )
+        self.assertHolidayName(name, dts)
+        self.assertHolidayName(name, self.no_estimated_holidays, range(1964, 2050))
+
+    def test_eid_al_fitr(self):
+        name = "Journée de la Korité"
+        dts = (
+            "2020-05-24",
+            "2021-05-12",
+            "2022-05-01",
+            "2023-04-22",
+            "2024-04-10",
+            "2025-03-30",
+        )
+        self.assertHolidayName(name, dts)
+        self.assertHolidayName(name, self.no_estimated_holidays, range(1964, 2050))
+        obs_dt = (
+            "2020-05-25",
+            "2022-05-02",
+            "2025-03-31",
+        )
+        self.assertHolidayName(f"{name} (observé)", self.no_estimated_holidays, obs_dt)
+        self.assertNoNonObservedHoliday(obs_dt)
+
+    def test_eid_al_adha(self):
+        name = "Journée de la Tabaski"
+        dts = (
+            "2020-07-31",
+            "2021-07-21",
+            "2022-07-10",
+            "2023-06-29",
+            "2024-06-17",
+        )
+        self.assertHolidayName(name, dts)
+        self.assertHolidayName(name, self.no_estimated_holidays, range(1964, 2050))
+        obs_dt = (
+            "2016-09-12",
+            "2019-08-12",
+            "2022-07-11",
+        )
+        self.assertHolidayName(f"{name} (observé)", self.no_estimated_holidays, obs_dt)
+        self.assertNoNonObservedHoliday(obs_dt)
+
+    def test_l10n_default(self):
+        self.assertLocalizedHolidays(
+            ("2024-01-01", "Jour de l'an"),
+            ("2024-04-01", "Lundi de Pâques"),
+            ("2024-04-04", "Fête de l'Indépendance"),
+            ("2024-04-10", "Journée de la Korité"),
+            ("2024-05-01", "Fête du Travail"),
+            ("2024-05-09", "Jeudi de l'Ascension"),
+            ("2024-05-20", "Lundi de Pentecôte"),
+            ("2024-06-17", "Journée de la Tabaski"),
+            ("2024-07-17", "Tamxarit"),
+            ("2024-08-15", "Assomption"),
+            ("2024-08-23", "Grand Magal de Touba"),
+            ("2024-09-15", "Journée du Maouloud"),
+            ("2024-11-01", "Toussaint"),
+            ("2024-12-25", "Noël"),
+        )
+
+    def test_l10n_en_us(self):
+        self.assertLocalizedHolidays(
+            "en_US",
+            ("2024-01-01", "New Year's Day"),
+            ("2024-04-01", "Easter Monday"),
+            ("2024-04-04", "Independence Day"),
+            ("2024-04-10", "Eid al-Fitr"),
+            ("2024-05-01", "Labor Day"),
+            ("2024-05-09", "Ascension Day"),
+            ("2024-05-20", "Whit Monday"),
+            ("2024-06-17", "Eid al-Adha"),
+            ("2024-07-17", "Ashura"),
+            ("2024-08-15", "Assumption Day"),
+            ("2024-08-23", "Grand Magal of Touba"),
+            ("2024-09-15", "Prophet's Birthday"),
+            ("2024-11-01", "All Saints' Day"),
+            ("2024-12-25", "Christmas Day"),
+        )