+
Skip to content

Conversation

AryaPhansalkar
Copy link
Contributor

Proposed change

  • Added Canary Islands holidays with localization in multiple languages (es, en_US, uk).
  • Added translation files for es,en_US and uk.
  • Canary Islands holidays are available as part of Spain holidays as subdivision CN.

Resolves #2662 .

Type of change

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

Checklist

Copy link
Contributor

coderabbitai bot commented Oct 1, 2025

Summary by CodeRabbit

  • New Features
    • Added holiday support for Canary Islands (IC), including recognition as a Spain subdivision. Supports English (US), Spanish, and Ukrainian locales.
  • Documentation
    • Updated Available Countries to 246 and added a Canary Islands entry with details.
    • Added localization resources for Canary Islands in English, Spanish, and Ukrainian.
  • Tests
    • Added tests covering aliases, holiday dates (from 1983), and localization for Canary Islands.
  • Chores
    • Updated contributors list.

Walkthrough

Adds Canary Islands (IC) as a new subdivision country entry (start year 1983) with module, registry export, locale PO files (en_US, es, uk), README update, tests, and a minor type annotation change in Spain; also adds a contributor entry.

Changes

Cohort / File(s) Summary
Contributors
CONTRIBUTORS
Added Arya Phansalkar.
Docs: README
README.md
Updated available countries count to 246 and inserted Canary Islands (IC) entry with loading notes and languages.
Country registry & exports
holidays/countries/__init__.py, holidays/registry.py
Exported CanaryIslands, IC, HolidaysIC; added registry entry canary_islands = ("CanaryIslands","IC","HolidaysIC").
New country module
holidays/countries/canary_islands.py
Added HolidaysIC (subdivision of Spain, code IC, parent subdivision CN, start_year=1983, default_language="es", supported ("en_US","es","uk")) and aliases CanaryIslands, IC.
Spain typing
holidays/countries/spain.py
Added type annotation: subdivisions: tuple[str, ...] = (...).
Localizations
holidays/locale/en_US/LC_MESSAGES/IC.po, holidays/locale/es/LC_MESSAGES/IC.po, holidays/locale/uk/LC_MESSAGES/IC.po
Added PO catalog headers/files for IC locale strings.
Tests
tests/countries/test_canary_islands.py
New tests: alias checks, no holidays before 1983, exact holiday dates for 1983 and 2025, and localization assertions (default, en_US, uk).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • arkid15r
  • PPsyrius

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The pull request also introduces a type annotation change in spain.py and updates the CONTRIBUTORS list, which are not directly related to adding Canary Islands holidays. Please separate or justify the unrelated type annotation update and the CONTRIBUTORS file change in a distinct commit or pull request to keep this PR focused on the Canary Islands holidays addition.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title clearly states the main addition of Canary Islands holidays and accurately reflects the core change made in the codebase.
Linked Issues Check ✅ Passed The changes implement the linked issue’s objectives by defining a new HolidaysIC class as a Spain subdivision, updating registry and imports, adding translations, and covering functionality with tests, thereby satisfying issue #2662.
Description Check ✅ Passed The description directly outlines the addition of Canary Islands holidays, the inclusion of localization files, and the subdivision integration under Spain, which aligns with the code changes.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29d2c1c and 3abb59a.

📒 Files selected for processing (5)
  • holidays/countries/canary_islands.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/IC.po (1 hunks)
  • holidays/locale/es/LC_MESSAGES/IC.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/IC.po (1 hunks)
  • tests/countries/test_canary_islands.py (1 hunks)
🧰 Additional context used
🧠 Learnings (21)
📚 Learning: 2025-06-28T10:39:19.185Z
Learnt from: KJhellico
PR: vacanza/holidays#2684
File: holidays/locale/it/LC_MESSAGES/SM.po:13-13
Timestamp: 2025-06-28T10:39:19.185Z
Learning: In the holidays project, .po file header comments use the format "# [Country] holidays." for default language files (without trailing hash) and "# [Country] holidays [locale] localization." for non-default language files (also without trailing hash).

Applied to files:

  • holidays/locale/es/LC_MESSAGES/IC.po
  • holidays/locale/en_US/LC_MESSAGES/IC.po
📚 Learning: 2025-09-26T13:58:49.363Z
Learnt from: KJhellico
PR: vacanza/holidays#2960
File: holidays/locale/ca/LC_MESSAGES/ES.po:148-151
Timestamp: 2025-09-26T13:58:49.363Z
Learning: In the holidays project, when translating holiday names in .po files, the msgstr should be a faithful translation of the original msgid (in the country's default language), not influenced by English commentary or common en_US names. For example, "Día de la Pascua Granada" (Spanish) correctly translates to "Dia de la Pasqua Granada" (Catalan), even though the English comment refers to it as "Whit Monday".

Applied to files:

  • holidays/locale/es/LC_MESSAGES/IC.po
  • holidays/locale/en_US/LC_MESSAGES/IC.po
  • holidays/locale/uk/LC_MESSAGES/IC.po
📚 Learning: 2025-06-11T18:32:25.595Z
Learnt from: ankushhKapoor
PR: vacanza/holidays#2601
File: holidays/locale/en_MN/LC_MESSAGES/MN.po:13-14
Timestamp: 2025-06-11T18:32:25.595Z
Learning: For non-default locale `.po` files, the header comment format is:
`# <Country> holidays <locale> localization.` (no trailing hash).

Applied to files:

  • holidays/locale/es/LC_MESSAGES/IC.po
📚 Learning: 2025-06-10T12:17:58.880Z
Learnt from: KJhellico
PR: vacanza/holidays#2608
File: holidays/locale/en_VC/LC_MESSAGES/VC.po:1-14
Timestamp: 2025-06-10T12:17:58.880Z
Learning: In the holidays project, .po files should use the full multi-line header format including the project description, authors, website, and license information, rather than a single-line comment format.

Applied to files:

  • holidays/locale/es/LC_MESSAGES/IC.po
📚 Learning: 2025-09-26T14:03:00.986Z
Learnt from: KJhellico
PR: vacanza/holidays#2960
File: holidays/locale/ca/LC_MESSAGES/ES.po:208-211
Timestamp: 2025-09-26T14:03:00.986Z
Learning: In the holidays project, proper place names and personal names should not be translated in localization comments, even when following en_US conventions. For example, "País Vasco" should remain as-is rather than being translated to "Basque Country" in comments.

Applied to files:

  • holidays/locale/es/LC_MESSAGES/IC.po
📚 Learning: 2025-03-30T18:25:07.087Z
Learnt from: KJhellico
PR: vacanza/holidays#2388
File: holidays/locale/en_CI/LC_MESSAGES/CI.po:88-88
Timestamp: 2025-03-30T18:25:07.087Z
Learning: In the holidays library, localization files have a specific structure: message comments are in standard English (en_US) describing the holiday, while actual translations (msgstr) should use the locale-specific terminology (e.g., en_CI for Ivory Coast English). For example, "Night of Power" in standard English is translated as "Lailatou-Kadr" in Ivory Coast English.

Applied to files:

  • holidays/locale/en_US/LC_MESSAGES/IC.po
  • holidays/locale/uk/LC_MESSAGES/IC.po
📚 Learning: 2025-05-06T15:25:44.333Z
Learnt from: KJhellico
PR: vacanza/holidays#2530
File: holidays/locale/ca/LC_MESSAGES/AD.po:31-40
Timestamp: 2025-05-06T15:25:44.333Z
Learning: In the Holidays project, msgid fields in localization files contain strings in the entity's default language (as defined by default_language attribute), not English source strings as in standard gettext implementations.

Applied to files:

  • holidays/locale/en_US/LC_MESSAGES/IC.po
📚 Learning: 2025-07-04T08:53:54.102Z
Learnt from: PPsyrius
PR: vacanza/holidays#2654
File: holidays/locale/de/LC_MESSAGES/CV.po:57-60
Timestamp: 2025-07-04T08:53:54.102Z
Learning: For Cape Verde German localization, holiday translations should follow Cape Verde-specific German terminology as found in sources like feelcaboverde.com, rather than standard German usage. The German translation choices are source-specific to Cape Verde context.

Applied to files:

  • holidays/locale/en_US/LC_MESSAGES/IC.po
  • holidays/locale/uk/LC_MESSAGES/IC.po
📚 Learning: 2025-04-05T04:47:27.213Z
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-04-05T04:29:38.042Z
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:85-86
Timestamp: 2025-04-05T04:29:38.042Z
Learning: For testing holiday implementations in the vacanza/holidays repository, recommend using `from tests.common import CommonCountryTests` as the base class instead of directly using `unittest.TestCase` to maintain consistency with project conventions and leverage common test utilities.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-08-08T14:37:03.045Z
Learnt from: KJhellico
PR: vacanza/holidays#2774
File: tests/countries/test_liberia.py:15-16
Timestamp: 2025-08-08T14:37:03.045Z
Learning: When adding a new country in vacanza/holidays, also re-export it in holidays/countries/__init__.py (e.g., from .liberia import Liberia, LR, LBR) so tests and users can import from holidays.countries consistently.

Applied to files:

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

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-05-06T21:07:11.577Z
Learnt from: KJhellico
PR: vacanza/holidays#2530
File: tests/countries/test_andorra.py:23-28
Timestamp: 2025-05-06T21:07:11.577Z
Learning: In the holidays project, test methods for country holidays follow a standard form where year ranges are explicitly recreated in each test method rather than being stored as class variables, to maintain consistency across all country tests.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-08-24T13:01:51.370Z
Learnt from: Wasif-Shahzad
PR: vacanza/holidays#2852
File: tests/countries/test_tajikistan.py:26-28
Timestamp: 2025-08-24T13:01:51.370Z
Learning: In the holidays project country test files, the standard method name for testing country aliases (ISO codes) is `test_country_aliases`, not `test_aliases`. This naming convention is consistently used across all country test files.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-06-16T15:48:48.680Z
Learnt from: PPsyrius
PR: vacanza/holidays#2615
File: tests/countries/test_anguilla.py:1-12
Timestamp: 2025-06-16T15:48:48.680Z
Learning: Test files in the holidays repository follow a standardized structure without module or class docstrings. All country test files use the same pattern: license header, imports, and class definition (`class Test{Country}(CommonCountryTests, TestCase):`) without docstrings. This is an established codebase convention that should be maintained for consistency.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-08-20T19:46:15.625Z
Learnt from: KJhellico
PR: vacanza/holidays#2833
File: tests/countries/test_uganda.py:15-0
Timestamp: 2025-08-20T19:46:15.625Z
Learning: In the holidays project, the standard import pattern for country test files is `from holidays.countries.<country> import Country, CODE1, CODE2` (direct module import), used by ~75% of country test files. Only a minority (~25%) use the aggregated public API import `from holidays.countries import Country, CODE1, CODE2`. The direct module import pattern should be used for new country test files to follow the established convention.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-04-05T04:50:40.752Z
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-06-18T17:01:58.067Z
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_wallis_and_futuna.py:19-23
Timestamp: 2025-06-18T17:01:58.067Z
Learning: In the vacanza/holidays repository, the standard pattern for test class setUpClass methods is `super().setUpClass(HolidayClass)` where HolidayClass is passed as the first argument. This is the correct signature used across all country test files.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-06-18T17:01:58.067Z
Learnt from: PPsyrius
PR: vacanza/holidays#2642
File: tests/countries/test_wallis_and_futuna.py:19-23
Timestamp: 2025-06-18T17:01:58.067Z
Learning: In the vacanza/holidays repository, the standard pattern for test class setUpClass methods is `super().setUpClass(HolidayClass)` or `super().setUpClass(HolidayClass, years=...)` where HolidayClass is passed as the first argument. This is the correct signature that matches the CommonCountryTests.setUpClass method which accepts test_class as the first parameter after cls. Pylint warnings about parameter count mismatch are false positives when comparing against TestCase.setUpClass instead of the immediate parent CommonCountryTests.setUpClass.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-09-03T14:05:10.592Z
Learnt from: PPsyrius
PR: vacanza/holidays#2881
File: tests/countries/test_aruba.py:77-79
Timestamp: 2025-09-03T14:05:10.592Z
Learning: The assertNoHolidayName helper method in the vacanza/holidays test framework accepts both individual years (scalars) and iterables of years, making calls like assertNoHolidayName(name, AW.start_year, range(2023, 2050)) valid where AW.start_year is a single integer year.

Applied to files:

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

Applied to files:

  • tests/countries/test_canary_islands.py
🧬 Code graph analysis (2)
holidays/countries/canary_islands.py (2)
holidays/countries/spain.py (1)
  • Spain (26-734)
holidays/mixins/child_entity.py (1)
  • ChildEntity (19-43)
tests/countries/test_canary_islands.py (2)
tests/common.py (5)
  • TestCase (31-370)
  • assertAliases (124-133)
  • assertNoHolidays (324-326)
  • assertHolidays (231-233)
  • assertLocalizedHolidays (359-370)
holidays/countries/canary_islands.py (3)
  • HolidaysIC (17-32)
  • CanaryIslands (35-36)
  • IC (39-40)
🔇 Additional comments (7)
holidays/locale/en_US/LC_MESSAGES/IC.po (1)

13-14: Header style looks good.

Comment line matches project convention for non-default locales.

holidays/countries/canary_islands.py (1)

17-33: Solid ChildEntity alias for ES-CN; start_year gate is correct.

MRO and CN mapping are correct; 1983 gating matches autonomy timeline.

Please confirm ES-CN special rules (Epiphany moves 2013/2019, 2021 exceptions) are intended to carry over unchanged for IC.

holidays/locale/es/LC_MESSAGES/IC.po (1)

13-14: Header matches convention.

Default-language PO header looks correct.

tests/countries/test_canary_islands.py (4)

13-26: Test harness setup is on-point.

Direct module import and setUpClass(HolidaysIC) align with project norms.


79-94: en_US assertions look right; keep them in sync with IC.po.

Once IC en_US translations are added, these remain stable and decoupled from ES.


96-111: Lock uk expectations by backing them with IC.po entries.

Populate uk IC.po as suggested so these don’t depend on ES catalogs.


47-61: Add a 2021 special-case check for CN rules.

ES-CN has notable exceptions (e.g., observed/moved days in certain years). Add a 2021 assertion to lock behavior.

     def test_2025(self):
         self.assertHolidays(
             CanaryIslands(years=2025),
@@
         )
+
+    def test_2021_special_cases(self):
+        # Add checks for CN-specific exceptions in 2021.
+        # May 30, 2021 was Sunday; confirm expected handling for Canary Day.
+        # Adjust if ES-CN logic observes/moves differently.
+        self.assertHolidays(
+            CanaryIslands(years=2021),
+            ("2021-05-30", "Día de Canarias"),
+            # Add any moved/observed assertions here if applicable.
+        )
⛔ Skipped due to learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2881
File: tests/countries/test_indonesia.py:221-223
Timestamp: 2025-09-28T05:42:12.777Z
Learning: In tests/countries/test_indonesia.py, the manual set inclusion checks using get_named and years_found for Lunar New Year (test_lunar_new_year) and Vesak Day (test_vesak_day) are intentional and should remain until both holidays get their own `{insert}_no_estimated` flags implemented, rather than using standard harness assertions like assertHolidayName/assertNoHolidayName.
Learnt from: PPsyrius
PR: vacanza/holidays#2386
File: tests/countries/test_nepal.py:499-536
Timestamp: 2025-04-05T06:49:06.217Z
Learning: In the holidays project, test files follow a dual testing approach: individual methods test specific holidays across multiple years, while comprehensive year-specific tests (e.g., `test_2025`) verify all holidays for a specific year in a single assertion. Both approaches serve different testing purposes and complement each other.
Learnt from: KJhellico
PR: vacanza/holidays#2623
File: tests/countries/test_christmas_island.py:136-146
Timestamp: 2025-07-09T21:16:35.145Z
Learning: In Christmas Island's holiday implementation, the test_christmas_day method cannot use assertNoNonObservedHoliday because in some years observed Christmas Day overlaps with Boxing Day when both holidays are moved due to weekend conflicts, causing the standard non-observed holiday check to fail inappropriately.
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.
Learnt from: PPsyrius
PR: vacanza/holidays#2881
File: tests/countries/test_barbados.py:21-23
Timestamp: 2025-09-14T16:03:13.558Z
Learning: In tests/countries/test_barbados.py, using years_non_observed=range(2000, 2024) is intentional because all observed holiday examples fall within 2001-2023, making this range appropriate for limiting testing to years where observed holidays actually exist in the test data.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Ruff (0.13.2)
holidays/countries/canary_islands.py

�[1;31mruff failed�[0m
�[1mCause:�[0m Failed to load configuration /ruff.toml
�[1mCause:�[0m Failed to parse /ruff.toml
�[1mCause:�[0m TOML parse error at line 26, column 3
|
26 | "RSE100", # Use of assert detected
| ^^^^^^^^
Unknown rule selector: RSE100

tests/countries/test_canary_islands.py

�[1;31mruff failed�[0m
�[1mCause:�[0m Failed to load configuration /ruff.toml
�[1mCause:�[0m Failed to parse /ruff.toml
�[1mCause:�[0m TOML parse error at line 26, column 3
|
26 | "RSE100", # Use of assert detected
| ^^^^^^^^
Unknown rule selector: RSE100


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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
holidays/locale/uk/LC_MESSAGES/IC.po (1)

1-29: Missing translation entries for Ukrainian locale.

The file contains only the PO header with no msgid/msgstr translation pairs. However, tests/countries/test_canary_islands.py lines 96-111 (test_l10n_uk) expect specific Ukrainian translations like "Новий рік", "Богоявлення", etc. Without the translation entries in this file, the Ukrainian localization will fail.

You need to add the complete set of holiday translation entries. Based on the test expectations, the file should include entries like:

+"X-Source-Language: es\n"
+
+#. New Year's Day
+msgid "Año Nuevo"
+msgstr "Новий рік"
+
+#. Epiphany
+msgid "Epifanía del Señor"
+msgstr "Богоявлення"
+
+#. Maundy Thursday
+msgid "Jueves Santo"
+msgstr "Великий четвер"
+
+#. Good Friday
+msgid "Viernes Santo"
+msgstr "Страсна пʼятниця"
+
+#. Labor Day
+msgid "Fiesta del Trabajo"
+msgstr "День праці"
+
+#. Day of the Canary Islands
+msgid "Día de Canarias"
+msgstr "День Канарських островів"
+
+#. Assumption Day
+msgid "Asunción de la Virgen"
+msgstr "Внебовзяття Пресвятої Діви Марії"
+
+#. National Day
+msgid "Fiesta Nacional de España"
+msgstr "Національний день Іспанії"
+
+#. All Saints' Day
+msgid "Todos los Santos"
+msgstr "День усіх святих"
+
+#. Constitution Day
+msgid "Día de la Constitución Española"
+msgstr "День Конституції Іспанії"
+
+#. Immaculate Conception
+msgid "Inmaculada Concepción"
+msgstr "Непорочне зачаття Діви Марії"
+
+#. Christmas Day
+msgid "Natividad del Señor"
+msgstr "Різдво Христове"
holidays/locale/en_US/LC_MESSAGES/IC.po (1)

1-29: Missing translation entries for en_US locale.

The file contains only the PO header with no msgid/msgstr translation pairs. However, tests/countries/test_canary_islands.py lines 79-94 (test_l10n_en_us) expect specific English translations like "New Year's Day", "Epiphany", etc. Without the translation entries in this file, the en_US localization will fail.

Add the complete set of holiday translation entries based on the test expectations:

+"X-Source-Language: es\n"
+
+#. New Year's Day
+msgid "Año Nuevo"
+msgstr "New Year's Day"
+
+#. Epiphany
+msgid "Epifanía del Señor"
+msgstr "Epiphany"
+
+#. Maundy Thursday
+msgid "Jueves Santo"
+msgstr "Maundy Thursday"
+
+#. Good Friday
+msgid "Viernes Santo"
+msgstr "Good Friday"
+
+#. Labor Day
+msgid "Fiesta del Trabajo"
+msgstr "Labor Day"
+
+#. Day of the Canary Islands
+msgid "Día de Canarias"
+msgstr "Day of the Canary Islands"
+
+#. Assumption Day
+msgid "Asunción de la Virgen"
+msgstr "Assumption Day"
+
+#. National Day
+msgid "Fiesta Nacional de España"
+msgstr "National Day"
+
+#. All Saints' Day
+msgid "Todos los Santos"
+msgstr "All Saints' Day"
+
+#. Constitution Day
+msgid "Día de la Constitución Española"
+msgstr "Constitution Day"
+
+#. Immaculate Conception
+msgid "Inmaculada Concepción"
+msgstr "Immaculate Conception"
+
+#. Christmas Day
+msgid "Natividad del Señor"
+msgstr "Christmas Day"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c68e6d6 and 29d2c1c.

📒 Files selected for processing (10)
  • CONTRIBUTORS (1 hunks)
  • README.md (2 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/countries/canary_islands.py (1 hunks)
  • holidays/countries/spain.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/IC.po (1 hunks)
  • holidays/locale/es/LC_MESSAGES/IC.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/IC.po (1 hunks)
  • holidays/registry.py (1 hunks)
  • tests/countries/test_canary_islands.py (1 hunks)
🧰 Additional context used
🧠 Learnings (16)
📚 Learning: 2025-06-28T10:39:19.185Z
Learnt from: KJhellico
PR: vacanza/holidays#2684
File: holidays/locale/it/LC_MESSAGES/SM.po:13-13
Timestamp: 2025-06-28T10:39:19.185Z
Learning: In the holidays project, .po file header comments use the format "# [Country] holidays." for default language files (without trailing hash) and "# [Country] holidays [locale] localization." for non-default language files (also without trailing hash).

Applied to files:

  • holidays/locale/es/LC_MESSAGES/IC.po
  • holidays/locale/en_US/LC_MESSAGES/IC.po
📚 Learning: 2025-09-26T13:58:49.350Z
Learnt from: KJhellico
PR: vacanza/holidays#2960
File: holidays/locale/ca/LC_MESSAGES/ES.po:148-151
Timestamp: 2025-09-26T13:58:49.350Z
Learning: In the holidays project, when translating holiday names in .po files, the msgstr should be a faithful translation of the original msgid (in the country's default language), not influenced by English commentary or common en_US names. For example, "Día de la Pascua Granada" (Spanish) correctly translates to "Dia de la Pasqua Granada" (Catalan), even though the English comment refers to it as "Whit Monday".

Applied to files:

  • holidays/locale/es/LC_MESSAGES/IC.po
  • holidays/locale/en_US/LC_MESSAGES/IC.po
  • holidays/locale/uk/LC_MESSAGES/IC.po
📚 Learning: 2025-08-08T14:37:03.045Z
Learnt from: KJhellico
PR: vacanza/holidays#2774
File: tests/countries/test_liberia.py:15-16
Timestamp: 2025-08-08T14:37:03.045Z
Learning: In holidays/countries/__init__.py, re-export country classes using absolute imports (e.g., 'from holidays.countries.liberia import Liberia, LR, LBR') and keep alphabetical ordering (e.g., Lesotho, Liberia, Libya). Avoid relative imports in this file.

Applied to files:

  • holidays/countries/__init__.py
📚 Learning: 2025-08-08T14:37:03.045Z
Learnt from: KJhellico
PR: vacanza/holidays#2774
File: tests/countries/test_liberia.py:15-16
Timestamp: 2025-08-08T14:37:03.045Z
Learning: When adding a new country in vacanza/holidays, also re-export it in holidays/countries/__init__.py (e.g., from .liberia import Liberia, LR, LBR) so tests and users can import from holidays.countries consistently.

Applied to files:

  • holidays/countries/__init__.py
📚 Learning: 2025-08-09T18:31:23.218Z
Learnt from: KJhellico
PR: vacanza/holidays#2778
File: tests/countries/test_kiribati.py:15-15
Timestamp: 2025-08-09T18:31:23.218Z
Learning: In the holidays project test files, the standard import pattern is `from holidays.countries.<country> import Country, CODE1, CODE2` (used in ~97% of test files), not `from holidays.countries import Country, CODE1, CODE2`. Only a few exceptions (Suriname, Sierra Leone, Mauritius, Mali, Ivory Coast, Guyana) use the aggregated import pattern.

Applied to files:

  • holidays/countries/__init__.py
📚 Learning: 2025-04-18T21:13:55.589Z
Learnt from: KJhellico
PR: vacanza/holidays#2483
File: holidays/registry.py:177-177
Timestamp: 2025-04-18T21:13:55.589Z
Learning: In the holidays/registry.py file, COUNTRIES dictionary entries should use the class name (without spaces) as the first element of the tuple (e.g., "TurksAndCaicosIslands"), not the human-readable country name with spaces.

Applied to files:

  • holidays/registry.py
📚 Learning: 2025-07-10T11:00:13.195Z
Learnt from: KJhellico
PR: vacanza/holidays#2623
File: README.md:0-0
Timestamp: 2025-07-10T11:00:13.195Z
Learning: The COUNTRIES dictionary in holidays/registry.py contains 211 entries as confirmed by KJhellico in PR #2623, not 214 as previously calculated.

Applied to files:

  • holidays/registry.py
📚 Learning: 2025-03-30T18:25:07.087Z
Learnt from: KJhellico
PR: vacanza/holidays#2388
File: holidays/locale/en_CI/LC_MESSAGES/CI.po:88-88
Timestamp: 2025-03-30T18:25:07.087Z
Learning: In the holidays library, localization files have a specific structure: message comments are in standard English (en_US) describing the holiday, while actual translations (msgstr) should use the locale-specific terminology (e.g., en_CI for Ivory Coast English). For example, "Night of Power" in standard English is translated as "Lailatou-Kadr" in Ivory Coast English.

Applied to files:

  • holidays/locale/en_US/LC_MESSAGES/IC.po
  • holidays/locale/uk/LC_MESSAGES/IC.po
📚 Learning: 2025-05-06T15:25:44.333Z
Learnt from: KJhellico
PR: vacanza/holidays#2530
File: holidays/locale/ca/LC_MESSAGES/AD.po:31-40
Timestamp: 2025-05-06T15:25:44.333Z
Learning: In the Holidays project, msgid fields in localization files contain strings in the entity's default language (as defined by default_language attribute), not English source strings as in standard gettext implementations.

Applied to files:

  • holidays/locale/en_US/LC_MESSAGES/IC.po
📚 Learning: 2025-07-12T20:54:28.749Z
Learnt from: KJhellico
PR: vacanza/holidays#2719
File: README.md:108-108
Timestamp: 2025-07-12T20:54:28.749Z
Learning: In PR #2719 adding Faroe Islands, KJhellico confirmed that the country count in README.md should be updated from 213 to 214, making 214 the accurate total after this addition.

Applied to files:

  • README.md
📚 Learning: 2025-04-05T04:47:27.213Z
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-04-05T04:29:38.042Z
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:85-86
Timestamp: 2025-04-05T04:29:38.042Z
Learning: For testing holiday implementations in the vacanza/holidays repository, recommend using `from tests.common import CommonCountryTests` as the base class instead of directly using `unittest.TestCase` to maintain consistency with project conventions and leverage common test utilities.

Applied to files:

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

Applied to files:

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

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-04-05T04:50:40.752Z
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:31-49
Timestamp: 2025-04-05T04:50:40.752Z
Learning: For Turkmenistan holiday tests, use this class structure: `class TestTurkmenistan(CommonCountryTests, TestCase)` with imports `from unittest import TestCase`, `from holidays.countries import Turkmenistan, TM, TKM`, and `from tests.common import CommonCountryTests`. Ensure to call `super().setUp()` in the setUp method.

Applied to files:

  • tests/countries/test_canary_islands.py
📚 Learning: 2025-05-06T21:07:11.577Z
Learnt from: KJhellico
PR: vacanza/holidays#2530
File: tests/countries/test_andorra.py:23-28
Timestamp: 2025-05-06T21:07:11.577Z
Learning: In the holidays project, test methods for country holidays follow a standard form where year ranges are explicitly recreated in each test method rather than being stored as class variables, to maintain consistency across all country tests.

Applied to files:

  • tests/countries/test_canary_islands.py
🧬 Code graph analysis (3)
holidays/countries/canary_islands.py (2)
holidays/countries/spain.py (1)
  • Spain (26-734)
holidays/mixins/child_entity.py (1)
  • ChildEntity (19-43)
holidays/countries/__init__.py (1)
holidays/countries/canary_islands.py (3)
  • CanaryIslands (36-37)
  • IC (40-41)
  • HolidaysIC (17-33)
tests/countries/test_canary_islands.py (2)
tests/common.py (5)
  • TestCase (31-370)
  • assertAliases (124-133)
  • assertNoHolidays (324-326)
  • assertHolidays (231-233)
  • assertLocalizedHolidays (359-370)
holidays/countries/canary_islands.py (3)
  • HolidaysIC (17-33)
  • IC (40-41)
  • CanaryIslands (36-37)
🔇 Additional comments (15)
CONTRIBUTORS (1)

24-24: LGTM!

The contributor addition is correctly placed alphabetically and follows the project's naming conventions.

holidays/countries/spain.py (1)

80-100: LGTM!

The type annotation adds clarity to the subdivisions attribute without changing runtime behavior. This is a clean improvement that aids static type checking.

holidays/registry.py (1)

63-63: LGTM!

The registry entry follows the project's conventions correctly. The class name uses PascalCase without spaces, and the alphabetical placement between Canada and Cayman Islands is accurate.

README.md (2)

108-108: LGTM!

The country count is correctly incremented from 245 to 246.


430-435: LGTM!

The Canary Islands entry is well-formed and correctly positioned alphabetically. The subdivision note clearly indicates the relationship with Spain (ES, subdivision CN), and the language specification with es as default is consistent with project conventions.

tests/countries/test_canary_islands.py (5)

19-22: LGTM! Standard test class structure.

Follows the project convention of inheriting from CommonCountryTests and TestCase, with proper setUpClass initialization.


24-25: LGTM! Alias validation is correct.

Properly validates the three class aliases (HolidaysIC, IC, CanaryIslands) using the standard assertAliases helper.


27-28: LGTM! Pre-start-year validation is correct.

Properly tests that year 1982 (before start_year 1983) has no holidays.


63-111: LGTM! Localization tests follow standard patterns.

The three localization tests properly validate holiday names across the supported languages (es, en_US, uk). However, these tests depend on complete translation entries in the corresponding .po files, which appear to be missing (see comments on locale files).


47-61: No change required: in 2025 the Fiesta Nacional (12 Oct) in the Canary Islands is omitted—since it falls on a Sunday—and May 30 is used as the substitute holiday, so the 11-entry list is correct.

holidays/countries/__init__.py (1)

55-55: LGTM! Import follows project conventions.

The import is correctly placed in alphabetical order between Canada and Cayman Islands, uses the absolute import pattern, and exports all three aliases (CanaryIslands, IC, HolidaysIC).

holidays/countries/canary_islands.py (4)

13-14: LGTM! Imports are correct.

Both imports are necessary: Spain as the parent entity and ChildEntity for the subdivision mixin pattern.


17-33: LGTM! Well-structured class definition.

The class properly uses the ChildEntity mixin pattern to establish Canary Islands as a Spanish subdivision (CN) with its own ISO 3166-1 country code (IC). Metadata is complete and accurate:

  • start_year aligns with test coverage
  • language support matches the provided locale files
  • references provide helpful context

36-37: LGTM! Standard alias pattern.

Provides a descriptive class name alias for HolidaysIC.


40-41: LGTM! Standard ISO code alias.

Provides the two-letter ISO 3166-1 code alias (IC) for convenient access.

Copy link

codecov bot commented Oct 1, 2025

Codecov Report

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

Additional details and impacted files
@@            Coverage Diff            @@
##               dev     #2971   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          301       302    +1     
  Lines        17962     17974   +12     
  Branches      2319      2319           
=========================================
+ Hits         17962     17974   +12     

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

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

@KJhellico KJhellico changed the title Add canary islands Add Canary Islands holidays Oct 1, 2025
Copy link

sonarqubecloud bot commented Oct 2, 2025

Copy link
Collaborator

@PPsyrius PPsyrius left a comment

Choose a reason for hiding this comment

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

LGTM 🇮🇨

Copy link
Collaborator

@KJhellico KJhellico left a comment

Choose a reason for hiding this comment

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

LGTM.

@arkid15r arkid15r added this pull request to the merge queue Oct 3, 2025
Merged via the queue into vacanza:dev with commit f7860a8 Oct 3, 2025
36 checks passed
arkid15r added a commit that referenced this pull request Oct 3, 2025
@coderabbitai coderabbitai bot mentioned this pull request Oct 5, 2025
9 tasks
@arkid15r arkid15r mentioned this pull request Oct 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Canary Islands holidays

4 participants

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