Skip to content

Update India Holidays: Fix National Holidays#3578

Open
ankushhKapoor wants to merge 48 commits into
vacanza:devfrom
ankushhKapoor:fix-national-holidays
Open

Update India Holidays: Fix National Holidays#3578
ankushhKapoor wants to merge 48 commits into
vacanza:devfrom
ankushhKapoor:fix-national-holidays

Conversation

@ankushhKapoor

@ankushhKapoor ankushhKapoor commented May 14, 2026

Copy link
Copy Markdown
Contributor

Proposed change

Fix national holidays of India.

Resources:
Official Notices collection

Part of GSoC and #3382

Type of change

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

Checklist

@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added Dr. B.R. Ambedkar's Jayanti, regional foundation days, and additional Hindu calendar observances.
    • Expanded Hindu celebration date database with new holidays including Basant Panchami, Guru Ravidas Jayanti, and Vishu.
    • Added comprehensive translations for Indian holidays across multiple languages.
  • Changes

    • Clarified holiday names (e.g., Diwali (Deepavali), Janmashtami (Vaishnava), Id-ul-Zuha (Bakrid)).
    • Refined public vs. optional holiday classifications for Hindu festivals.
    • Enhanced regional holiday observances across Indian states and union territories.

Walkthrough

Extends the Hindu calendar with seven new holiday types and corresponding date tables. Migrates India's holiday generator to include StaticHolidays, adds IndiaStaticHolidays, renames/adds national and optional holidays with year-gated logic, updates subdivisions, and adds IndiaIslamicHolidays date constants. Updates eleven locale PO files and refactors the India test suite with skip_years/hindu_range helper semantics.

Changes

India Holiday Expansion

Layer / File(s) Summary
Hindu calendar: new constants, date tables, and accessors
holidays/calendars/hindu.py
Adds seven new module-level holiday constants (BASANT_PANCHAMI, GURU_RAVIDAS_JAYANTI, KARWA_CHAUTH, NARAKA_CHATURDASHI, RATH_YATRA, SWAMI_DAYANAND_SARASWATI_JAYANTI, VISHU) with per-year lookup tables, corrects RAM_NAVAMI_DATES[2008] and GURU_GOBIND_SINGH_JAYANTI_DATES[2011], and adds seven accessor methods to _HinduLunisolar.
HinduCalendarHolidays: new wrapper methods and _ram_navami property
holidays/groups/hindu.py
Adds _ram_navami computed property, imports isleap and MAY, and introduces eleven new wrapper methods (_add_basant_panchami, _add_diwali_south_india, _add_guru_ravidas_jayanti, _add_holika_dahan, _add_karwa_chauth, _add_naraka_chaturdashi, _add_rabindranath_birthday, _add_rath_yatra, _add_swami_dayanand_saraswati_jayanti, _add_vaisakhadi, _add_vishu).
India generator: national/optional/subdivision/Islamic/static holidays
holidays/countries/india.py
Adds StaticHolidays to India base classes; introduces year-gate constants for Holi/Janmashtami/Maha Shivaratri; rewrites national public holidays with renamed labels and Ram Navami observed logic; reworks optional holidays with Dussehra variants, gated Hindu festivals, Ganesh Chaturthi, Onam, Christmas Eve; updates multiple subdivisions; and introduces IndiaStaticHolidays and IndiaIslamicHolidays date constants.
India test suite: helper refactor, new tests, label updates
tests/countries/test_india.py
Extends _assertHinduHolidayHelper with hindu_range and skip_years; adds tests for Dr. B. R. Ambedkar's Jayanti, Guru Tegh Bahadur's Martyrdom Day, Christmas Eve, Deepavali (South India), three Dussehra variants, Guru Ravidas Birthday, and Naraka Chaturdashi; renames Diwali/Janmashtami tests to canonical labels; updates test_2018, test_2018_optional, and all test_l10n_* assertions.
IN.po locale catalogs: msgid/msgstr updates across 11 languages
holidays/locale/bn/..., holidays/locale/en_IN/..., holidays/locale/en_US/..., holidays/locale/gu/..., holidays/locale/hi/..., holidays/locale/kn/..., holidays/locale/ml/..., holidays/locale/mr/..., holidays/locale/pa/..., holidays/locale/ta/..., holidays/locale/te/LC_MESSAGES/IN.po
Renames DiwaliDiwali (Deepavali), JanmashtamiJanmashtami (Vaishnava), BakridId-ul-Zuha (Bakrid) across all 11 locale catalogs; adds Dr. B. R. Ambedkar's Jayanti, Holi, Ram Navami, large blocks of new festival/observance entries, Andhra Pradesh Foundation Day, and deduplicates Gudi Padwa, Vaisakhi, Lohri, Pongal; appends Basant Panchami, Sri Panchami, Ganesh Chaturthi, Vinayak Chaturthi, Janmashtami (Smarta).

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • vacanza/holidays#3524: Substantially refactors tests/countries/test_india.py including the shared _assertHinduHolidayHelper assertions and expected labels for updated India holiday names.
  • vacanza/holidays#3476: Modifies holidays/countries/india.py's Andaman & Nicobar subdivision holiday population to add/adjust Onam, overlapping with the same subdivision generator logic changed here.
  • vacanza/holidays#3485: Refactors _assertHinduHolidayHelper and India Hindu test expectations in tests/countries/test_india.py, directly affecting tests changed in this PR.

Suggested reviewers

  • PPsyrius
  • arkid15r
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.30% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: fixing India's national holidays, which aligns with the comprehensive updates to India holiday definitions, labels, and localization.
Description check ✅ Passed The description is directly related to the changeset, explaining the purpose of fixing Indian national holidays with reference to official sources and context (GSoC, issue #3382).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

❤️ Share

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

@ankushhKapoor

ankushhKapoor commented May 14, 2026

Copy link
Copy Markdown
Contributor Author

Right now a lot of tests are failing, made draft PR to get help with test functions assertion of Ram Navami, Maha Shivratri and Janmashtami.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
holidays/locale/te/LC_MESSAGES/IN.po (1)

103-105: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translator comment doesn't match msgid.

Same translator comment/msgid mismatch as in the other locale files.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/locale/te/LC_MESSAGES/IN.po` around lines 103 - 105, The translator
comment above the msgid is incorrect; replace or update the comment to match the
msgid "Id-ul-Zuha (Bakrid)" (e.g., change the existing comment "Eid al-Adha." to
"Id-ul-Zuha (Bakrid).") so the comment and msgid are consistent; apply the same
correction pattern used in other locale files where this mismatch occurred.
holidays/locale/ta/LC_MESSAGES/IN.po (1)

103-105: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translator comment doesn't match msgid.

Same issue as in the Punjabi locale file: translator comment says "Eid al-Adha" but msgid is "Id-ul-Zuha (Bakrid)". This appears in all locale files under review, suggesting a systematic issue with the Python source comment or the .po file generation process.

Based on learnings, verify the Python source comment and regenerate locale files with make l10n.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/locale/ta/LC_MESSAGES/IN.po` around lines 103 - 105, The translator
comment for the entry with msgid "Id-ul-Zuha (Bakrid)" is incorrect ("Eid
al-Adha"); update the source comment in the Python code that generates this
catalog so the translator comment matches the msgid (or the canonical event
name) and then regenerate the .po files by running make l10n, ensuring the PO
entry for msgid "Id-ul-Zuha (Bakrid)" in LC_MESSAGES/IN.po (and other locales)
carries the corrected translator comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@holidays/locale/kn/LC_MESSAGES/IN.po`:
- Around line 39-43: The Kannada translation for the msgid "Dr. B. R. Ambedkar's
Jayanti" has a typo in msgstr ("ಡಾ|| ಬಿ.ಆರ್.ಅಂಬೇಡ್ಕರ್ ಜಯಂತಿ"); edit the msgstr
for that exact msgid to replace the incorrect "ಡಾ||" with the correct "ಡಾ." so
the entry reads "ಡಾ. ಬಿ.ಆರ್.ಅಂಬೇಡ್ಕರ್ ಜಯಂತಿ".

---

Duplicate comments:
In `@holidays/locale/ta/LC_MESSAGES/IN.po`:
- Around line 103-105: The translator comment for the entry with msgid
"Id-ul-Zuha (Bakrid)" is incorrect ("Eid al-Adha"); update the source comment in
the Python code that generates this catalog so the translator comment matches
the msgid (or the canonical event name) and then regenerate the .po files by
running make l10n, ensuring the PO entry for msgid "Id-ul-Zuha (Bakrid)" in
LC_MESSAGES/IN.po (and other locales) carries the corrected translator comment.

In `@holidays/locale/te/LC_MESSAGES/IN.po`:
- Around line 103-105: The translator comment above the msgid is incorrect;
replace or update the comment to match the msgid "Id-ul-Zuha (Bakrid)" (e.g.,
change the existing comment "Eid al-Adha." to "Id-ul-Zuha (Bakrid).") so the
comment and msgid are consistent; apply the same correction pattern used in
other locale files where this mismatch occurred.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4b266fed-ccd6-439e-aada-3f5a3f46ad08

📥 Commits

Reviewing files that changed from the base of the PR and between 8086e60 and 39a9335.

📒 Files selected for processing (13)
  • holidays/countries/india.py
  • holidays/locale/bn/LC_MESSAGES/IN.po
  • holidays/locale/en_IN/LC_MESSAGES/IN.po
  • holidays/locale/en_US/LC_MESSAGES/IN.po
  • holidays/locale/gu/LC_MESSAGES/IN.po
  • holidays/locale/hi/LC_MESSAGES/IN.po
  • holidays/locale/kn/LC_MESSAGES/IN.po
  • holidays/locale/ml/LC_MESSAGES/IN.po
  • holidays/locale/mr/LC_MESSAGES/IN.po
  • holidays/locale/pa/LC_MESSAGES/IN.po
  • holidays/locale/ta/LC_MESSAGES/IN.po
  • holidays/locale/te/LC_MESSAGES/IN.po
  • tests/countries/test_india.py

Comment thread holidays/locale/kn/LC_MESSAGES/IN.po Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

4 issues found across 13 files

Confidence score: 3/5

  • There is a concrete user-facing correctness risk in holidays/countries/india.py: adding Ambedkar Jayanti as a national holiday may require matching _add_holiday_apr_14 updates across many subdivision methods, so some regions could return inconsistent holiday sets.
  • The .po updates in holidays/locale/gu/LC_MESSAGES/IN.po and holidays/locale/en_US/LC_MESSAGES/IN.po show stale/mismatched extracted comments versus source, which suggests manual edits and raises maintainability/regeneration drift risk.
  • holidays/locale/hi/LC_MESSAGES/IN.po has a smaller consistency issue (Diwali extracted comment mismatch) that is likely low impact at runtime but signals localization metadata is out of sync.
  • Pay close attention to holidays/countries/india.py, holidays/locale/gu/LC_MESSAGES/IN.po, holidays/locale/en_US/LC_MESSAGES/IN.po, and holidays/locale/hi/LC_MESSAGES/IN.po - verify subdivision coverage for Apr 14 and regenerate locale files to align extracted comments with source.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="holidays/locale/hi/LC_MESSAGES/IN.po">

<violation number="1" location="holidays/locale/hi/LC_MESSAGES/IN.po:56">
P3: Extracted comment doesn't match the Python source comment (`# Diwali.` at india.py:214). This should be `#. Diwali.` to be consistent with how other entries work (e.g., `#. Eid al-Adha.` for msgid `"Id-ul-Zuha (Bakrid)"`). Consider regenerating via `make l10n` rather than hand-editing.

(Based on your team's feedback about managing translation files through the l10n pipeline.) [FEEDBACK_USED]</violation>
</file>

<file name="holidays/countries/india.py">

<violation number="1" location="holidays/countries/india.py:194">
P2: Now that "Dr. B. R. Ambedkar's Jayanti" is added as a national public holiday, the same `_add_holiday_apr_14` calls in ~25 subdivision methods (AN, AP, BR, CH, CG, GA, GJ, HR, HP, JK, JH, KA, KL, LA, MH, MP, OD, PY, PB, RJ, SK, TN, TS, UK, UP, WB) are redundant. Other national holidays (Republic Day, Independence Day, Gandhi Jayanti) are not repeated at the subdivision level. These subdivision-level additions should be removed to follow the same pattern.</violation>
</file>

<file name="holidays/locale/gu/LC_MESSAGES/IN.po">

<violation number="1" location="holidays/locale/gu/LC_MESSAGES/IN.po:56">
P2: This `.po` file appears to have been hand-edited rather than generated via `make l10n`. The extracted comments (`#.` lines) differ from the `en_IN` reference locale — e.g., Diwali's comment here is `#. Diwali (Deepavali).` while the generated reference has `#. Diwali.`, and multi-line extracted comments for Ambedkar and Janmashtami are missing. Run `make l10n` to regenerate the file from source, then fill in the `msgstr` translations.

(Based on your team's feedback about managing translation files through the l10n pipeline.) [FEEDBACK_USED]</violation>
</file>

<file name="holidays/locale/en_US/LC_MESSAGES/IN.po">

<violation number="1" location="holidays/locale/en_US/LC_MESSAGES/IN.po:41">
P2: This extracted comment doesn't match any source code comment — all instances in `india.py` use `"Dr. B. R. Ambedkar's Jayanti"` (with possessive 's). This stale comment suggests the file was hand-edited rather than regenerated via `make l10n`. Run `make l10n` to keep the .po file consistent with source strings.

(Based on your team's feedback about managing translation files through the l10n pipeline.) [FEEDBACK_USED]</violation>
</file>

Tip: cubic used a learning from your PR history. Let your coding agent read cubic learnings directly with the cubic MCP.
Fix all with cubic

Comment thread holidays/countries/india.py
Comment thread holidays/locale/gu/LC_MESSAGES/IN.po Outdated
Comment thread holidays/locale/en_US/LC_MESSAGES/IN.po Outdated
Comment thread holidays/locale/hi/LC_MESSAGES/IN.po Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/locale/en_IN/LC_MESSAGES/IN.po Outdated
Comment thread holidays/countries/india.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (5)
tests/countries/test_india.py (5)

186-215: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Docstring is helpful but has a small typo and an over-strong claim.

Two tiny cleanups in the new docstring block:

  • Line 209: "works for both public & optional assertion" is missing a space after the comma — "skip_years,works""skip_years, works".
  • Lines 211–214 describe SUN_TO_NONE behavior, but the helper itself is generic and doesn't know about that observed rule; the explanation belongs in the India definitions file, not here. Consider trimming to "the range-wide assertion uses the non-observed catalog, so observance shifts don't affect membership."

Both are nit-level; happy to roll them into the larger helper refactor.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/countries/test_india.py` around lines 186 - 215, Fix two docstring
issues in the helper in tests/countries/test_india.py: correct the typo by
adding a space after the comma in "skip_years, works" (near the parameter
description for skip_years) and replace the over-specific SUN_TO_NONE
explanation with a shorter, generic sentence such as "the range-wide assertion
uses the non-observed catalog, so observance shifts don't affect membership"
(update the paragraph that currently references SUN_TO_NONE/observance rules).
Ensure edits are made inside the same docstring that documents hindu_range and
skip_years so the helper signature (hindu_range, skip_years) remains unchanged.

316-333: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

This is the failing Janmashtami (Vaishnava) test — the optional call collides with the public assertion.

Walking through the helper with category_optional=True and skip_years=None (Line 333 doesn't pass any), control falls into the else branch at Line 241, which calls self.assertNoHolidayName(name) for the whole catalog. But Lines 318–326 just asserted "Janmashtami (Vaishnava)" as a public holiday on 2020-08-12, 2021-08-30, etc., so the absence check is guaranteed to fail.

You almost certainly want to pass the public years as skip_years to the optional call (mirroring the Maha Shivaratri / Ram Navami pattern), and drop the redundant assertNoHolidayName(name, 2008, 2017) since the helper's assertNoOptionalHolidayName(name, *skip_years) already enforces optional absence on those years. Also note Line 332 currently asserts name is absent from public on 2008/2017, which contradicts the optional dts on the very next line and would only hold if those dates are not public — please double-check the source-of-truth list.

🔧 Suggested fix shape
     def test_janmashtami_vaishnava(self):
         name = "Janmashtami (Vaishnava)"
         dts = (
             "2020-08-12",
             "2021-08-30",
             "2022-08-19",
             "2023-09-07",
             "2024-08-26",
             "2025-08-16",
         )
-        self._assertHinduHolidayHelper(name, dts)
+        public_years = {2020, 2021, 2022, 2023, 2024, 2025, ...}  # all years where it's public
+        self._assertHinduHolidayHelper(name, dts)
         # OPTIONAL.
         dts = (
             "2008-08-24",
             "2017-08-15",
         )
-        self.assertNoHolidayName(name, 2008, 2017)
-        self._assertHinduHolidayHelper(name, dts, category_optional=True)
+        self._assertHinduHolidayHelper(
+            name,
+            dts,
+            category_optional=True,
+            skip_years={y for y in self.hindu_full_range if y not in {2008, 2017}},
+        )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/countries/test_india.py` around lines 316 - 333, The
test_janmashtami_vaishnava currently asserts the holiday as public for certain
years then calls the helper with category_optional=True without supplying
skip_years, which makes the helper call assertNoHolidayName(name) for the entire
catalog and causes a collision; fix by removing the redundant
self.assertNoHolidayName(name, 2008, 2017) and call
self._assertHinduHolidayHelper(name, dts, category_optional=True,
skip_years=(2020,2021,2022,2023,2024,2025)) (or the equivalent tuple of public
years) so the helper will skip those public years when asserting optional-only
absence via assertNoOptionalHolidayName and avoid contradicting the earlier
public assertions.

179-275: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

The skip_years semantics are inverted between caller sites and very easy to misread.

Inside the helper (Lines 217–218), skip_years is treated as years to remove from the effective range. That's fine for Maha Shivaratri's public branch (Line 372). But the optional branches in test_maha_shivaratri (Line 385) and test_ram_navami (Line 518) pass {y for y in self.hindu_full_range if y not in skip_years} — i.e., they invert the variable so the name skip_years ends up meaning "years to keep". Two different intents are encoded under the same parameter name across consecutive lines, which is the kind of thing that will bite the next contributor.

Two cleaner options:

  1. Keep the helper signature but introduce a sibling only_years parameter, and let callers use one or the other. The helper then computes effective_range once with clear semantics.
  2. Have callers compute the final list themselves and pass it directly as hindu_range, dropping skip_years entirely. The optional Ram Navami call becomes hindu_range=(2002, 2012, 2018, 2022, 2025, 2029), which reads exactly like what's asserted.

Option 2 is the smaller diff and removes the inverse-set trick at call sites. Also worth adding to the docstring a one-liner that warns skip_years is not symmetric with the public/optional pair.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/countries/test_india.py` around lines 179 - 275, The helper
_assertHinduHolidayHelper has inverted semantics for skip_years vs caller
intent; remove the skip_years parameter and its handling (the effective_range
computation that filters out skip_years) and require callers (e.g.,
test_maha_shivaratri and test_ram_navami) to pass the exact years via
hindu_range (or self.hindu_full_range) so the helper only uses hindu_range
directly; update the helper signature to drop skip_years, delete the lines
computing effective_range from skip_years, adjust callers to pass
hindu_range=(...) or hindu_range=self.hindu_full_range as appropriate, and add a
one-line note in the helper docstring that callers must pass explicit
hindu_range when they need a subset.

496-519: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Ram Navami non-optional path will assert the holiday in every year of hindu_full_range, but dts only covers four years.

Line 504 calls the helper without skip_years, so effective_range = self.hindu_full_range (35 years). The helper then runs assertNonObservedHolidayName(name, effective_range) and asserts Ram Navami is public in every one of those years. But dts lists only 2020, 2021, 2023, 2024 — notably missing 2022 and 2025, which the optional block at Lines 506–513 includes as years where Ram Navami is optional, not public.

That's likely the failing Ram Navami test the PR description mentions. The fix is the same shape as Maha Shivaratri: pass a skip_years set covering the optional-only years (and any others not emitted as public) to the non-optional call.

Separately, the inverted-set pattern on Line 518 is confusing — passing hindu_range=(2002, 2012, 2018, 2022, 2025, 2029) directly would be far easier to audit than computing the 29-year complement.

🔧 Suggested shape
     def test_ram_navami(self):
         name = "Ram Navami"
         dts = (
             "2020-04-02",
             "2021-04-21",
             "2023-03-30",
             "2024-04-17",
         )
-        self._assertHinduHolidayHelper(name, dts)
+        optional_years = {2002, 2012, 2018, 2022, 2025, 2029}
+        self._assertHinduHolidayHelper(name, dts, skip_years=optional_years)
         # OPTIONAL.
-        skip_years = {2002, 2012, 2018, 2022, 2025, 2029}
         dts = (
             "2002-04-21",
             "2012-04-01",
             "2018-03-25",
             "2022-04-10",
             "2025-04-06",
         )
         self._assertHinduHolidayHelper(
             name,
             dts,
             category_optional=True,
-            skip_years={y for y in self.hindu_full_range if y not in skip_years},
+            hindu_range=tuple(optional_years),
         )

(Pairs with the hindu_range/only_years refactor proposed above.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/countries/test_india.py` around lines 496 - 519, The non-optional Ram
Navami test calls _assertHinduHolidayHelper(name, dts) but fails because it
asserts the holiday across the entire self.hindu_full_range; include a
skip_years argument listing years that are optional-only (e.g., the set used in
the optional block: {2002, 2012, 2018, 2022, 2025, 2029}) when calling
_assertHinduHolidayHelper for the non-optional path (reference
_assertHinduHolidayHelper and the variable dts), and replace the confusing
inverted-set expression in the optional call with an explicit hindu_range or
explicit skip_years list to make the intent clear.

734-770: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Resolve the Ambedkar Jayanti assertion conflict—national and selective subdiv declarations contradict each other.

The generator adds this holiday both nationally (line 198) and explicitly in 26 subdivisions. The test asserts it's national, then expects it to exist only in those 26 subdivisions. If national holidays flow to all subdivisions, subdivisions like DL and MZ will inherit it and break the else: assertNoHolidayName(...) check at line 770.

Choose one:

  • Make it truly national: Remove the 26 explicit subdiv entries; the national registration suffices.
  • Keep it selective: Remove the national-level registration; each of the 26 subdivisions registers it independently and others don't.

Either way, the current dual declaration is unsustainable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/countries/test_india.py` around lines 734 - 770, The test
test_dr_b_r_ambedkars_jayanti fails because "Dr. B. R. Ambedkar's Jayanti" is
registered both nationally and again in 26 subdivisions; choose one
approach—here, make it selective: remove the national-level registration of the
holiday (the generator/registration that creates a nationwide "Dr. B. R.
Ambedkar's Jayanti" entry) so only the explicit subdiv registrations remain,
leaving test_dr_b_r_ambedkars_jayanti's current assertions valid.
♻️ Duplicate comments (1)
holidays/locale/kn/LC_MESSAGES/IN.po (1)

39-42: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix typo in Kannada translation for Ambedkar Jayanti.

The msgstr uses ಡಾ|| which should be ಡಾ. (period instead of double pipes).

Proposed fix
-msgstr "ಡಾ|| ಬಿ.ಆರ್.ಅಂಬೇಡ್ಕರ್ ಜಯಂತಿ"
+msgstr "ಡಾ. ಬಿ.ಆರ್.ಅಂಬೇಡ್ಕರ್ ಜಯಂತಿ"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/locale/kn/LC_MESSAGES/IN.po` around lines 39 - 42, Replace the typo
in the Kannada translation for the msgid "Dr. B. R. Ambedkar's Jayanti": update
the msgstr value currently containing "ಡಾ|| ಬಿ.ಆರ್.ಅಂಬೇಡ್ಕರ್ ಜಯಂತಿ" to use a
period instead of double pipes, i.e. "ಡಾ. ಬಿ.ಆರ್.ಅಂಬೇಡ್ಕರ್ ಜಯಂತಿ", preserving
spacing and punctuation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@holidays/calendars/hindu.py`:
- Line 1170: The RAM_NAVAMI_DATES table in _HinduLunisolar (symbol:
_HinduLunisolar.RAM_NAVAMI_DATES) incorrectly encodes an observance shift for
2008 as (APR, 14); revert that entry to the true astronomical date (APR, 13) so
the shared lunisolar calendar remains raw, and let the India observance pipeline
(see india.py and the _add_observed(..., rule=SUN_TO_NONE) / SUN_ONLY logic)
perform the gazette transfer to Apr 14 for India-specific PUBLIC holidays.

In `@holidays/countries/india.py`:
- Around line 235-252: The current hard-coded exclusion set around the Maha
Shivaratri addition is brittle and may be wrong; replace the inline literal set
with a single named constant (e.g. MAHA_SHIVARATRI_OBSERVED_YEARS) and decide
whether an inclusion set (years when Maha Shivaratri is observed) or an
exclusion set is correct based on the official notices — if the observed years
are the smaller group, invert the logic to check membership in the inclusion
constant; update the check in the method where
self._add_maha_shivaratri(tr("Maha Shivaratri")) is called and mirror the exact
same constant/logic in the optional-category counterpart (the block that
currently spans lines ~311-328) so both stay in sync.
- Around line 197-198: Remove the duplicate per-subdivision Ambedkar Jayanti
entries now that it's added nationally: find the per-subdivision population
methods (the various _populate_subdiv_*_public_holidays methods) and delete the
calls to self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) for the
listed subdivisions (AN, AP, BR, CH, CG, GA, GJ, HR, HP, JK, JH, KA, KL, LA, MH,
MP, OD, PY, PB, RJ, SK, TN, TS, UK, UP, WB), leaving only the national-level
self._add_holiday_apr_14(...) in the main _populate_public_holidays;
alternatively, if you prefer the gated approach, replace those subdivision calls
with a single conditional in the subdivision dispatcher that adds Ambedkar
Jayanti only when subdiv not in {"AS","DL","MZ","NL"} using the existing
self._add_holiday_apr_14 method.
- Around line 301-303: Replace the boolean chain checking specific years with a
set membership test: in the block that currently tests "if self._year == 2008 or
self._year == 2017" use a set (or tuple) membership check against self._year
(matching the style used at the public counterpart around line 228) and keep the
call to self._add_janmashtami(tr("Janmashtami (Vaishnava)")) unchanged; this
consolidates the year checks into a single efficient expression.
- Around line 569-572: Remove the duplicate Ambedkar Jayanti entry (the
self._add_holiday_apr_14(tr("Dr. B. R. Ambedkar's Jayanti")) call) from the
Tamil Nadu section and keep the Puthandu entry, but replace the hardcoded
self._add_holiday_apr_14(tr("Puthandu (Tamil New Year)")) with a calendar-driven
helper like _add_puthandu or compute_puthandu_date that mirrors the approach
used for Pongal/Thiruvalluvar Day (use the existing calendar helper patterns to
compute Mesha Sankranti/solar transit into Aries and return Apr 13–15 as
appropriate, falling back to Apr 14 if computation fails), and call that helper
instead of the static _add_holiday_apr_14; ensure to use the same tr(...) label
when adding the computed date.

In `@tests/countries/test_india.py`:
- Around line 313-314: The test_dussehra_mahanavami currently only asserts a
single date ("2002-10-14"); replace or augment that with a full-range check
using the _assertHinduHolidayHelper to validate the holiday across
hindu_start_year..hindu_end_year and confirm absence outside that range, and if
this is meant to be a single-year variant, explicitly assert absence for the
adjacent years (e.g., years before and after 2002) so the test locks in that
behavior; update references to _assertHinduHolidayHelper and keep or remove the
single assertHolidayName("Dussehra (Mahanavami)", "2002-10-14") accordingly.
- Around line 234-253: The else branch inside the category_optional=True
handling incorrectly calls assertNoHolidayName(name) for the entire catalog when
skip_years is empty, which conflicts with prior public assertions; remove that
else branch (or make it an opt-in flag) so the helper only asserts optional-side
facts (assertOptionalHolidayName, assertOptionalNonObservedHolidayName,
assertNoOptionalHolidayName, assertNoOptionalNonObservedHolidayName) and do not
call assertNoHolidayName(name) unless the caller explicitly requests it or
provides skip_years; update callers that expect a pure “no-public” assertion to
call assertNoHolidayName(name) themselves.

---

Outside diff comments:
In `@tests/countries/test_india.py`:
- Around line 186-215: Fix two docstring issues in the helper in
tests/countries/test_india.py: correct the typo by adding a space after the
comma in "skip_years, works" (near the parameter description for skip_years) and
replace the over-specific SUN_TO_NONE explanation with a shorter, generic
sentence such as "the range-wide assertion uses the non-observed catalog, so
observance shifts don't affect membership" (update the paragraph that currently
references SUN_TO_NONE/observance rules). Ensure edits are made inside the same
docstring that documents hindu_range and skip_years so the helper signature
(hindu_range, skip_years) remains unchanged.
- Around line 316-333: The test_janmashtami_vaishnava currently asserts the
holiday as public for certain years then calls the helper with
category_optional=True without supplying skip_years, which makes the helper call
assertNoHolidayName(name) for the entire catalog and causes a collision; fix by
removing the redundant self.assertNoHolidayName(name, 2008, 2017) and call
self._assertHinduHolidayHelper(name, dts, category_optional=True,
skip_years=(2020,2021,2022,2023,2024,2025)) (or the equivalent tuple of public
years) so the helper will skip those public years when asserting optional-only
absence via assertNoOptionalHolidayName and avoid contradicting the earlier
public assertions.
- Around line 179-275: The helper _assertHinduHolidayHelper has inverted
semantics for skip_years vs caller intent; remove the skip_years parameter and
its handling (the effective_range computation that filters out skip_years) and
require callers (e.g., test_maha_shivaratri and test_ram_navami) to pass the
exact years via hindu_range (or self.hindu_full_range) so the helper only uses
hindu_range directly; update the helper signature to drop skip_years, delete the
lines computing effective_range from skip_years, adjust callers to pass
hindu_range=(...) or hindu_range=self.hindu_full_range as appropriate, and add a
one-line note in the helper docstring that callers must pass explicit
hindu_range when they need a subset.
- Around line 496-519: The non-optional Ram Navami test calls
_assertHinduHolidayHelper(name, dts) but fails because it asserts the holiday
across the entire self.hindu_full_range; include a skip_years argument listing
years that are optional-only (e.g., the set used in the optional block: {2002,
2012, 2018, 2022, 2025, 2029}) when calling _assertHinduHolidayHelper for the
non-optional path (reference _assertHinduHolidayHelper and the variable dts),
and replace the confusing inverted-set expression in the optional call with an
explicit hindu_range or explicit skip_years list to make the intent clear.
- Around line 734-770: The test test_dr_b_r_ambedkars_jayanti fails because "Dr.
B. R. Ambedkar's Jayanti" is registered both nationally and again in 26
subdivisions; choose one approach—here, make it selective: remove the
national-level registration of the holiday (the generator/registration that
creates a nationwide "Dr. B. R. Ambedkar's Jayanti" entry) so only the explicit
subdiv registrations remain, leaving test_dr_b_r_ambedkars_jayanti's current
assertions valid.

---

Duplicate comments:
In `@holidays/locale/kn/LC_MESSAGES/IN.po`:
- Around line 39-42: Replace the typo in the Kannada translation for the msgid
"Dr. B. R. Ambedkar's Jayanti": update the msgstr value currently containing
"ಡಾ|| ಬಿ.ಆರ್.ಅಂಬೇಡ್ಕರ್ ಜಯಂತಿ" to use a period instead of double pipes, i.e. "ಡಾ.
ಬಿ.ಆರ್.ಅಂಬೇಡ್ಕರ್ ಜಯಂತಿ", preserving spacing and punctuation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: aed8dca5-6739-491f-9b5c-60bb2ff6ef23

📥 Commits

Reviewing files that changed from the base of the PR and between 39a9335 and 220d099.

📒 Files selected for processing (15)
  • holidays/calendars/hindu.py
  • holidays/countries/india.py
  • holidays/locale/bn/LC_MESSAGES/IN.po
  • holidays/locale/en_IN/LC_MESSAGES/IN.po
  • holidays/locale/en_US/LC_MESSAGES/IN.po
  • holidays/locale/gu/LC_MESSAGES/IN.po
  • holidays/locale/hi/LC_MESSAGES/IN.po
  • holidays/locale/kn/LC_MESSAGES/IN.po
  • holidays/locale/ml/LC_MESSAGES/IN.po
  • holidays/locale/mr/LC_MESSAGES/IN.po
  • holidays/locale/pa/LC_MESSAGES/IN.po
  • holidays/locale/ta/LC_MESSAGES/IN.po
  • holidays/locale/te/LC_MESSAGES/IN.po
  • holidays/observed_holiday_base.py
  • tests/countries/test_india.py

2006: (APR, 6),
2007: (MAR, 26),
2008: (APR, 13),
2008: (APR, 14),

@coderabbitai coderabbitai Bot May 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Don't bake an observance shift into the raw lunisolar calendar.

Ram Navami 2008 fell on Sunday, Apr 13 — that's the astronomical date the linked source (timeanddate.com) reports and what _HinduLunisolar.RAM_NAVAMI_DATES is supposed to hold. The Apr 14 observance is a gazette transfer because Apr 13 was a Sunday, and that's exactly what the new _add_observed(..., rule=SUN_TO_NONE) / SUN_ONLY plumbing in india.py is meant to handle (per the earlier reviewer thread).

If you hardcode 2008 to Apr 14 here, two problems follow:

  1. SUN_TO_NONE / SUN_ONLY will both see Monday and become no-ops for 2008 — the special-case logic the rest of this PR is built around silently breaks for this exact year.
  2. Any other country/locale that ever consumes RAM_NAVAMI_DATES will get an India-specific transferred date instead of the real lunar Ram Navami.

Please revert this entry to (APR, 13) and let the observance rule do the shift. If the gazette transfer to Apr 14 is the desired final output for India's PUBLIC category in 2008, that should be expressed via the observed-rule pipeline (or a country-level special-case), not by mutating the shared calendar table.

↩️ Suggested revert
-        2008: (APR, 14),
+        2008: (APR, 13),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
2008: (APR, 14),
2008: (APR, 13),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/calendars/hindu.py` at line 1170, The RAM_NAVAMI_DATES table in
_HinduLunisolar (symbol: _HinduLunisolar.RAM_NAVAMI_DATES) incorrectly encodes
an observance shift for 2008 as (APR, 14); revert that entry to the true
astronomical date (APR, 13) so the shared lunisolar calendar remains raw, and
let the India observance pipeline (see india.py and the _add_observed(...,
rule=SUN_TO_NONE) / SUN_ONLY logic) perform the gazette transfer to Apr 14 for
India-specific PUBLIC holidays.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

hmm, lets add it in CustomCalendar for India and keep date same in Hindu calendar.
In 2008, it spanned for 2 days Sunday, Monday and gov chose Monday as holiday.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

Good call. Let me check how the _CustomCalendar override pattern works so I can give you the exact implementation.


🏁 Script executed:

#!/bin/bash
# Check the CUSTOM_ATTR_POSTFIX value and _CustomCalendar structure
rg -n "CUSTOM_ATTR_POSTFIX" --type py -A2 -B2

echo "---"
# Find any existing usage of custom Hindu date overrides in country files
rg -n "RAM_NAVAMI_DATES_" --type py -A2 -B2

echo "---"
# See how _CustomHinduHolidays is used in country files
rg -n "_CustomHinduHolidays" --type py -A2 -B2

Length of output: 15493


@ankushhKapoor — solid approach. The _CustomHinduHolidays pattern is exactly the right tool here. Here's the implementation:

Step 1 — Revert hindu.py (as originally suggested):

-        2008: (APR, 14),
+        2008: (APR, 13),

Step 2 — In holidays/countries/india.py, add a country-specific custom class (following the same pattern as FijiHinduHolidays, NepalHinduHolidays, etc.):

from holidays.calendars import _CustomHinduHolidays

class IndiaHinduHolidays(_CustomHinduHolidays):
    # In 2008, Ram Navami spanned two tithis: Sunday Apr 13 and Monday Apr 14.
    # The government gazette designated Monday Apr 14 as the public holiday.
    RAM_NAVAMI_DATES = {
        2008: (APR, 14),
    }

Step 3 — Make sure the India class (or its HinduCalendarHolidays mixin wiring) uses IndiaHinduHolidays instead of the bare _HinduLunisolar. Other country files wire this in their __init__ by passing the custom class to the mixin — check how HinduCalendarHolidays is initialised in india.py and pass IndiaHinduHolidays there.

How it flows: _CustomCalendar's metaclass renames RAM_NAVAMI_DATESRAM_NAVAMI_DATES_CUSTOM_CALENDAR on the subclass. Then _get_holiday checks RAM_NAVAMI_DATES_CUSTOM_CALENDAR first — finds Apr 14 for 2008 — and never falls back to the base Apr 13. Since Apr 14 is a Monday, the SUN_TO_NONE/SUN_ONLY observance rules are also no-ops for that year, which is exactly what you want.


🧬 Code Graph Analysis Results

Filename: holidays/calendars/balinese_saka.py
Lines: 101-103

def _get_holiday(self, holiday: str, year: int) -> date | None:
        dt = getattr(self, f"{holiday}_DATES", {}).get(year, ())
        return date(year, *dt) if dt else None

Filename: holidays/calendars/hebrew.py
Lines: 1600-1602

def _get_holiday(self, holiday: str, year: int) -> date | None:
        dt = getattr(self, f"{holiday}_DATES", {}).get(year, ())
        return date(year, *dt) if dt else None

Filename: holidays/calendars/buddhist.py
Lines: 429-433

def _get_holiday(self, holiday: str, year: int) -> tuple[date | None, bool]:
        estimated_dates = getattr(self, f"{holiday}_DATES", {})
        exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {})
        dt = exact_dates.get(year, estimated_dates.get(year, ()))
        return date(year, *dt) if dt else None, year not in exact_dates

Filename: holidays/calendars/mongolian.py
Lines: 324-328

def _get_holiday(self, holiday: str, year: int) -> tuple[date | None, bool]:
        estimated_dates = getattr(self, f"{holiday}_DATES", {})
        exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {})
        dt = exact_dates.get(year, estimated_dates.get(year, ()))
        return date(year, *dt) if dt else None, year not in exact_dates

Filename: holidays/calendars/tibetan.py
Lines: 1424-1428

def _get_holiday(self, holiday: str, year: int) -> tuple[date | None, bool]:
        estimated_dates = getattr(self, f"{holiday}_DATES", {})
        exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {})
        dt = exact_dates.get(year, estimated_dates.get(year, ()))
        return date(year, *dt) if dt else None, year not in exact_dates

Filename: holidays/calendars/sinhala.py
Lines: 374-378

def _get_holiday(self, holiday: str, year: int) -> tuple[date | None, bool]:
        estimated_dates = getattr(self, f"{holiday}_DATES", {})
        exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {})
        dt = exact_dates.get(year, estimated_dates.get(year, ()))
        return date(year, *dt) if dt else None, year not in exact_dates

Filename: holidays/calendars/sinhala.py
Lines: 380-385

def _get_holiday_set(self, holiday: str, year: int) -> Iterable[tuple[date, bool]]:
        estimated_dates = getattr(self, f"{holiday}_DATES", {})
        exact_dates = getattr(self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {})
        for year in (year - 1, year):
            for dt in _normalize_tuple(exact_dates.get(year, estimated_dates.get(year, ()))):
                yield date(year, *dt), year not in exact_dates

Filename: holidays/calendars/chinese.py
Lines: 1360-1377

def _get_holiday(self, holiday: str, year: int, calendar=None) -> tuple[date | None, bool]:
        calendar = calendar or self.__calendar
        self.__verify_calendar(calendar)
        confirmed_dates = getattr(
            self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}
        )
        confirmed_years = getattr(
            self, f"{holiday}_DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", (0, 0)
        )
        estimated_dates = getattr(self, f"{holiday}_DATES", {})
        custom_calendar_dates = getattr(self, f"{calendar}_{holiday}_DATES", {})
        dt = confirmed_dates.get(
            year, custom_calendar_dates.get(year, estimated_dates.get(year, ()))
        )
        is_confirmed = year in confirmed_dates or (
            confirmed_years[0] <= year <= confirmed_years[1]
        )
        return date(year, *dt) if dt else None, not is_confirmed

Filename: holidays/holiday_base.py
Lines: 996-1019

def get(self, key: DateLike, default: str | Any = None) -> str | Any:
        """Retrieve the holiday name(s) for a given date.

        If the date is a holiday, returns the holiday name as a string.
        If multiple holidays fall on the same date, their names are joined by a semicolon (`;`).
        If the date is not a holiday, returns the provided `default` value (defaults to `None`).

        Args:
            key:
                The date expressed in one of the following types:

                * `datetime.date`
                * `datetime.datetime`
                * `float` or `int` (Unix timestamp)
                * `str` of any format recognized by `dateutil.parser.parse()`

            default:
                The default value to return if no value is found.

        Returns:
            The holiday name(s) as a string if the date is a holiday,
                or the `default` value otherwise.
        """
        return dict.get(self, self.__keytransform__(key), default)

Filename: holidays/calendars/islamic.py
Lines: 3983-4010

def _get_holiday(self, holiday: str, year: int) -> Iterable[tuple[date, bool]]:
        confirmed_dates = getattr(
            self, f"{holiday}_DATES_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", {}
        )
        confirmed_years = _normalize_tuple(
            getattr(
                self, f"{holiday}_DATES_CONFIRMED_YEARS_{_CustomCalendar.CUSTOM_ATTR_POSTFIX}", ()
            )
        )
        estimated_dates = getattr(self, f"{holiday}_DATES", {})
        calendar_delta_days = self.__calendar_delta_days

        for check_year in (year - 1, year):
            is_confirmed_year = check_year in confirmed_dates
            for dt in _normalize_tuple(
                confirmed_dates.get(check_year, estimated_dates.get(check_year, ()))
            ):
                is_confirmed = is_confirmed_year or any(
                    year_from <= check_year <= year_to for year_from, year_to in confirmed_years
                )

                holiday_date = date(check_year, *dt)
                yield (
                    _timedelta(holiday_date, calendar_delta_days)
                    if calendar_delta_days and not is_confirmed_year
                    else holiday_date,
                    not is_confirmed,
                )

Filename: holidays/helpers.py
Lines: 39-49

def _normalize_tuple(value):
    """Normalize tuple.

    :param data:
        Either a tuple or a tuple of tuples.

    :return:
        An unchanged object for tuple of tuples, e.g., ((JAN, 10), (DEC, 31)).
        An object put into a tuple otherwise, e.g., ((JAN, 10),).
    """
    return value if not value or isinstance(value[0], tuple) else (value,)

Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread tests/countries/test_india.py Outdated
Comment thread tests/countries/test_india.py Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

3 issues found across 15 files

Confidence score: 4/5

  • This PR looks safe to merge: all reported findings are low-to-moderate severity localization workflow issues (4/10), not clear runtime or security regressions.
  • The main risk is maintainability/churn in translated outputs because holidays/locale/ml/LC_MESSAGES/IN.po, holidays/locale/en_US/LC_MESSAGES/IN.po, and holidays/locale/hi/LC_MESSAGES/IN.po appear hand-edited instead of regenerated via the project l10n pipeline.
  • To reduce follow-up diffs and formatting inconsistencies, update source holiday strings in Python and regenerate .po files with make l10n per the documented workflow.
  • Pay close attention to holidays/locale/ml/LC_MESSAGES/IN.po, holidays/locale/en_US/LC_MESSAGES/IN.po, holidays/locale/hi/LC_MESSAGES/IN.po - they should be tool-generated to keep localization files consistent.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="holidays/locale/ml/LC_MESSAGES/IN.po">

<violation number="1" location="holidays/locale/ml/LC_MESSAGES/IN.po:20">
P2: This `.po` file appears to be hand-edited rather than regenerated via `make l10n`. Update the source strings in the Python code, then run `make l10n` to regenerate the translation files to maintain consistent formatting and entry ordering.

(Based on your team's feedback about managing translation files through the l10n pipeline.) [FEEDBACK_USED]</violation>
</file>

<file name="holidays/locale/en_US/LC_MESSAGES/IN.po">

<violation number="1" location="holidays/locale/en_US/LC_MESSAGES/IN.po:20">
P2: This `.po` file appears to be hand-edited rather than regenerated via `make l10n`. The proper workflow is to update the source `.py` holiday strings first, then run `make l10n` to let the tooling regenerate this file with consistent ordering and metadata.

(Based on your team's feedback about managing translation files through the l10n pipeline.) [FEEDBACK_USED]</violation>
</file>

<file name="holidays/locale/hi/LC_MESSAGES/IN.po">

<violation number="1" location="holidays/locale/hi/LC_MESSAGES/IN.po:20">
P2: This `.po` file appears to be hand-edited rather than generated by `make l10n`. The project has an l10n pipeline (`make l10n` → `generate_po_files.py`) that should produce these files from the source `.py` strings. Please update the source strings in `india.py` first (if not already done), then run `make l10n` to regenerate the `.po` file to ensure it stays in sync with the tooling's expected format and ordering.

(Based on your team's feedback about managing translation files through the l10n pipeline.) [FEEDBACK_USED]</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment thread holidays/locale/ml/LC_MESSAGES/IN.po Outdated
Comment thread holidays/locale/en_US/LC_MESSAGES/IN.po Outdated
Comment thread holidays/locale/hi/LC_MESSAGES/IN.po Outdated

@KJhellico KJhellico left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A few refactoring suggestions. I'd also want to note that _assertHinduHolidayHelper is becoming too complex.

Comment thread tests/countries/test_india.py Outdated
Comment thread tests/countries/test_india.py Outdated
Comment thread tests/countries/test_india.py Outdated
@ankushhKapoor

Copy link
Copy Markdown
Contributor Author

I'd also want to note that _assertHinduHolidayHelper is becoming too complex.

Agreed, but should I continue with current implementation or need some changes in it ?

@KJhellico

Copy link
Copy Markdown
Collaborator

Agreed, but should I continue with current implementation or need some changes in it ?

Let's leave it at that for now. There will be many more changes in the tests anyway.

Co-authored-by: ~Jhellico <KJhellico@users.noreply.github.com>
Signed-off-by: Ankush Kapoor <work.ankushkapoor1626@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/countries/test_india.py`:
- Around line 323-330: The split-holiday tests call the helper and
assertNoHolidayName across public vs optional halves but don't pass the same
skip_years to both, causing conflicting assertions; update the test cases (e.g.,
test_janmashtami_vaishnava, test_ram_navami and similar blocks around the shown
diff) so that both calls to self._assertHinduHolidayHelper and
self.assertNoHolidayName include the same skip_years argument (or pass
skip_years to both helper invocations) so the public-side and optional-side
checks consistently skip the same years.
- Around line 183-184: The annotations use Iterable in the function signature
containing parameters "hindu_range: Iterable[int] | None" and "skip_years:
set[int] | None" but Iterable is not imported; add "from typing import Iterable"
(or include Iterable in the existing typing import) at the top of the module so
the annotation resolves at import time (alternatively enable postponed
evaluation with "from __future__ import annotations" if you prefer).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 31e0e44f-8a11-4f4c-85e7-c9750df8aa53

📥 Commits

Reviewing files that changed from the base of the PR and between 220d099 and cca69a8.

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

Comment thread tests/countries/test_india.py
Comment thread tests/countries/test_india.py Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 15 files

Confidence score: 3/5

  • There is a concrete regression risk in holidays/countries/india.py: adding a common Holi holiday conflicts with Maharashtra’s existing Holi override, which can produce duplicate Holi entries (notably for 2026).
  • Given the high severity/confidence signal (7/10, 9/10) and user-facing calendar output impact, this is more than a minor cleanup issue and warrants a fix or validation before merge.
  • Pay close attention to holidays/countries/india.py - resolve state-specific override interactions so Holi is emitted once per applicable date/state.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="holidays/countries/india.py">

<violation number="1" location="holidays/countries/india.py:259">
P1: The new common Holi addition creates a conflicting duplicate Holi date for Maharashtra (notably 2026), because MH already defines its own public Holi date override.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
Re-trigger cubic

Comment thread holidays/countries/india.py
@codecov

codecov Bot commented May 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (4f25c7f) to head (0aa34ea).

Additional details and impacted files
@@            Coverage Diff             @@
##               dev     #3578    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files          315       315            
  Lines        18843     18955   +112     
  Branches      2411      2431    +20     
==========================================
+ Hits         18843     18955   +112     

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/countries/test_india.py`:
- Around line 255-273: The helper contains stale commented-out assertions
(references: assertHolidayName, assertNoHolidayName,
assertNoSuNonObservedHolidayName, assertNoNonObservedHolidayName and variables
subdivs, subdiv, holidays, non_obs_holidays) which should be removed or
reinstated; either fully delete the commented blocks (the three commented
assert* lines and the commented non_obs_holidays line) to keep the helper
concise, or re-enable them by restoring correct current semantics (uncomment and
update arguments/variable names to match the active code) so there are no stray
commented assertions remaining.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c6cd9952-087a-4494-8745-8dbf9cd30fbb

📥 Commits

Reviewing files that changed from the base of the PR and between cca69a8 and fc92191.

📒 Files selected for processing (5)
  • holidays/countries/india.py
  • holidays/locale/bn/LC_MESSAGES/IN.po
  • holidays/locale/gu/LC_MESSAGES/IN.po
  • holidays/locale/mr/LC_MESSAGES/IN.po
  • tests/countries/test_india.py

Comment thread tests/countries/test_india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread tests/countries/test_india.py Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 15 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread holidays/locale/te/LC_MESSAGES/IN.po Outdated

@KJhellico KJhellico left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I've reviewed the available sources. ;)

Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated

@KJhellico KJhellico left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A few translation corrections:

Comment thread holidays/locale/en_US/LC_MESSAGES/IN.po Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
@sonarqubecloud

Copy link
Copy Markdown

Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
Comment thread holidays/countries/india.py Outdated
@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@holidays/groups/hindu.py`:
- Around line 31-36: The `_ram_navami` property is missing a return type
annotation. Add the return type annotation `date | None` to the property
definition, as it returns the first element of the tuple from `ram_navami_date`
which can be either a date object or None. This ensures consistency with type
annotation standards throughout the codebase.

In `@holidays/locale/kn/LC_MESSAGES/IN.po`:
- Around line 215-218: The msgstr value for "Ganesh Chaturthi / Vinayak
Chaturthi" in the Kannada locale file is written in Malayalam script instead of
Kannada script. Replace the Malayalam text in the msgstr field with the correct
Kannada script translation to ensure Kannada users receive the proper locale
output. The msgid identifier "Ganesh Chaturthi / Vinayak Chaturthi" marks the
exact entry that needs correction.

In `@holidays/locale/ml/LC_MESSAGES/IN.po`:
- Around line 451-453: The msgstr for "Janmashtami (Smarta)" in the Malayalam
locale file (holidays/locale/ml/LC_MESSAGES/IN.po) is currently written in
Kannada script instead of Malayalam script, breaking the Malayalam localization.
Replace the Kannada script translation (ಜನ್ಮಾಷ್ಟಮಿ (ಸ್ಮಾರ್ತ)) with the correct
Malayalam script translation for this holiday to ensure proper localization for
Malayalam users.

In `@holidays/locale/mr/LC_MESSAGES/IN.po`:
- Around line 451-453: The msgstr value for the message ID "Janmashtami
(Smarta)" in the Marathi locale file is currently written in Kannada script
instead of Marathi script. Replace the Kannada script text in the msgstr field
with the correct Marathi script translation for "Janmashtami (Smarta)" to ensure
the Marathi localization output displays correctly.

In `@holidays/locale/te/LC_MESSAGES/IN.po`:
- Around line 183-185: The Telugu locale catalog file
(holidays/locale/te/LC_MESSAGES/IN.po) contains three entries where the msgstr
values are written in Tamil script instead of Telugu script, which will cause
incorrect rendering for Telugu users. At lines 183-185 (Vaisakhadi entry), lines
191-193, and lines 263-265, replace each Tamil-script msgstr value with the
correct Telugu-script translation for the corresponding holiday name to ensure
the Telugu localization displays properly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8d2461e7-8f45-4412-943f-c8fc3fa9e93e

📥 Commits

Reviewing files that changed from the base of the PR and between f58ef3e and 0aa34ea.

📒 Files selected for processing (15)
  • holidays/calendars/hindu.py
  • holidays/countries/india.py
  • holidays/groups/hindu.py
  • holidays/locale/bn/LC_MESSAGES/IN.po
  • holidays/locale/en_IN/LC_MESSAGES/IN.po
  • holidays/locale/en_US/LC_MESSAGES/IN.po
  • holidays/locale/gu/LC_MESSAGES/IN.po
  • holidays/locale/hi/LC_MESSAGES/IN.po
  • holidays/locale/kn/LC_MESSAGES/IN.po
  • holidays/locale/ml/LC_MESSAGES/IN.po
  • holidays/locale/mr/LC_MESSAGES/IN.po
  • holidays/locale/pa/LC_MESSAGES/IN.po
  • holidays/locale/ta/LC_MESSAGES/IN.po
  • holidays/locale/te/LC_MESSAGES/IN.po
  • tests/countries/test_india.py

Comment thread holidays/groups/hindu.py
Comment on lines +31 to +36
@property
def _ram_navami(self):
"""
Return Ram Navami date.
"""
return self._hindu_calendar.ram_navami_date(self._year)[0]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Add return type annotation to _ram_navami property.

The property is missing a return type annotation. Since it returns date | None (the first element of the tuple from ram_navami_date), add the annotation for consistency with the rest of the codebase.

♻️ Proposed fix
     `@property`
-    def _ram_navami(self):
+    def _ram_navami(self) -> date | None:
         """
         Return Ram Navami date.
         """
         return self._hindu_calendar.ram_navami_date(self._year)[0]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@property
def _ram_navami(self):
"""
Return Ram Navami date.
"""
return self._hindu_calendar.ram_navami_date(self._year)[0]
`@property`
def _ram_navami(self) -> date | None:
"""
Return Ram Navami date.
"""
return self._hindu_calendar.ram_navami_date(self._year)[0]
🧰 Tools
🪛 Ruff (0.15.15)

[warning] 32-32: Missing return type annotation for private function _ram_navami

(ANN202)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/groups/hindu.py` around lines 31 - 36, The `_ram_navami` property is
missing a return type annotation. Add the return type annotation `date | None`
to the property definition, as it returns the first element of the tuple from
`ram_navami_date` which can be either a date object or None. This ensures
consistency with type annotation standards throughout the codebase.

Source: Linters/SAST tools

Comment on lines +215 to +218
#. Ganesh Chaturthi / Vinayak Chaturthi.
msgid "Ganesh Chaturthi / Vinayak Chaturthi"
msgstr "ഗണേശ ചതുർത്ഥി / വിനായക ചതുർത്ഥി"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix wrong-language script in Kannada translation entry.

msgstr for Ganesh Chaturthi / Vinayak Chaturthi is in Malayalam script, so Kannada users will get the wrong locale output.

Proposed fix
 msgid "Ganesh Chaturthi / Vinayak Chaturthi"
-msgstr "ഗണേശ ചതുർത്ഥി / വിനായക ചതുർത്ഥി"
+msgstr "ಗಣೇಶ ಚತುರ್ಥಿ / ವಿನಾಯಕ ಚತುರ್ಥಿ"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/locale/kn/LC_MESSAGES/IN.po` around lines 215 - 218, The msgstr
value for "Ganesh Chaturthi / Vinayak Chaturthi" in the Kannada locale file is
written in Malayalam script instead of Kannada script. Replace the Malayalam
text in the msgstr field with the correct Kannada script translation to ensure
Kannada users receive the proper locale output. The msgid identifier "Ganesh
Chaturthi / Vinayak Chaturthi" marks the exact entry that needs correction.

Comment on lines +451 to +453
#. Janmashtami (Smarta).
msgid "Janmashtami (Smarta)"
msgstr "ಜನ್ಮಾಷ್ಟಮಿ (ಸ್ಮಾರ್ತ)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Replace non-Malayalam msgstr for Janmashtami (Smarta).

The translation is currently in Kannada script, so Malayalam localization for this holiday is broken.

Proposed fix
 msgid "Janmashtami (Smarta)"
-msgstr "ಜನ್ಮಾಷ್ಟಮಿ (ಸ್ಮಾರ್ತ)"
+msgstr "ജന്മാഷ്ടമി (സ്മാർത്ത)"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#. Janmashtami (Smarta).
msgid "Janmashtami (Smarta)"
msgstr "ಜನ್ಮಾಷ್ಟಮಿ (ಸ್ಮಾರ್ತ)"
#. Janmashtami (Smarta).
msgid "Janmashtami (Smarta)"
msgstr "ജന്മാഷ്ടമി (സ്മാർത്ത)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/locale/ml/LC_MESSAGES/IN.po` around lines 451 - 453, The msgstr for
"Janmashtami (Smarta)" in the Malayalam locale file
(holidays/locale/ml/LC_MESSAGES/IN.po) is currently written in Kannada script
instead of Malayalam script, breaking the Malayalam localization. Replace the
Kannada script translation (ಜನ್ಮಾಷ್ಟಮಿ (ಸ್ಮಾರ್ತ)) with the correct Malayalam
script translation for this holiday to ensure proper localization for Malayalam
users.

Comment on lines +451 to +453
#. Janmashtami (Smarta).
msgid "Janmashtami (Smarta)"
msgstr "ಜನ್ಮಾಷ್ಟಮಿ (ಸ್ಮಾರ್ತ)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use Marathi script for Janmashtami (Smarta) translation.

Current msgstr is in Kannada script, which breaks Marathi localization output for this key.

Proposed fix
 msgid "Janmashtami (Smarta)"
-msgstr "ಜನ್ಮಾಷ್ಟಮಿ (ಸ್ಮಾರ್ತ)"
+msgstr "जन्माष्टमी (स्मार्त)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/locale/mr/LC_MESSAGES/IN.po` around lines 451 - 453, The msgstr
value for the message ID "Janmashtami (Smarta)" in the Marathi locale file is
currently written in Kannada script instead of Marathi script. Replace the
Kannada script text in the msgstr field with the correct Marathi script
translation for "Janmashtami (Smarta)" to ensure the Marathi localization output
displays correctly.

Comment on lines +183 to +185
#. Vaisakhadi.
msgid "Vaisakhadi"
msgstr "வைசாகதி"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix non-Telugu msgstr values in the Telugu catalog.

Three entries use Tamil-script text in holidays/locale/te/LC_MESSAGES/IN.po, so Telugu localization will render incorrectly for those holidays (Line 185, Line 193, Line 265).

Suggested patch
 #. Vaisakhadi.
 msgid "Vaisakhadi"
-msgstr "வைசாகதி"
+msgstr "వైశాఖాది"

 #. Vishu.
 msgid "Vishu"
-msgstr "விசு"
+msgstr "విషు"

 #. Ali's Birthday.
 msgid "Hazarat Ali's Birthday"
-msgstr "ஹஸ்ரத் அலியின் பிறந்தநாள்"
+msgstr "హజరత్ అలీ జన్మదినం"

Also applies to: 191-193, 263-265

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@holidays/locale/te/LC_MESSAGES/IN.po` around lines 183 - 185, The Telugu
locale catalog file (holidays/locale/te/LC_MESSAGES/IN.po) contains three
entries where the msgstr values are written in Tamil script instead of Telugu
script, which will cause incorrect rendering for Telugu users. At lines 183-185
(Vaisakhadi entry), lines 191-193, and lines 263-265, replace each Tamil-script
msgstr value with the correct Telugu-script translation for the corresponding
holiday name to ensure the Telugu localization displays properly.

Comment on lines 459 to 461
# Palm Sunday.
self._add_palm_sunday(tr("Palm Sunday"))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
# Palm Sunday.
self._add_palm_sunday(tr("Palm Sunday"))

Comment on lines +739 to +742
special_public_holidays = {
# Dussehra (Mahanavami).
2002: (OCT, 14, tr("Dussehra (Mahanavami)")),
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This needs to be placed after variables declaraation.

@@ -13,6 +13,8 @@
# mypy: disable-error-code=attr-defined

import warnings
from calendar import isleap
from collections.abc import Iterable
from unittest import TestCase

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It would be more convenient to arrange the tests in the same order as the holidays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants