Skip to content

Conversation

@Arynelson
Copy link
Contributor

@Arynelson Arynelson commented Apr 8, 2025

Holidays added for the island of Åland, an autonomous territory belonging to Finland

Resolves #2424 .

Type of change

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

Checklist

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 8, 2025

Summary by CodeRabbit

  • New Features
    • Added full support for Åland Islands holidays, including localized names and documentation updates.
    • Expanded and standardized Ethiopian holiday data and localization.
  • Bug Fixes
    • Corrected and updated holiday dates and names for Ethiopia, Singapore, Vietnam, and South Korea.
    • Fixed and clarified localization entries for multiple countries and languages.
  • Documentation
    • Updated supported country lists, localization notes, and author credits.
    • Adjusted security policy and removed outdated changelog entries.
  • Tests
    • Added and expanded test coverage for Åland Islands and Ethiopia, and refined tests for Singapore and Vietnam.
  • Chores
    • Updated dependencies and CI/CD workflows.
    • Improved internal configuration and removed obsolete pre-commit hooks.
  • Refactor
    • Streamlined internal logic for holiday calculations and localization handling.

Summary by CodeRabbit

  • New Features

    • Added support for Åland Islands holidays, including a dedicated holiday calendar and localization in multiple languages.
    • Åland's Autonomy Day is now recognized as a public holiday for the Åland Islands and as a subdivision-specific holiday in Finland.
  • Documentation

    • Updated documentation to include Åland Islands as a supported country, with details on codes, languages, and holiday categories.
  • Localization

    • Added and updated translation files for Åland Islands and Finland in English, Finnish, Swedish, and Ukrainian.
  • Tests

    • Introduced comprehensive tests for Åland Islands holidays and enhanced Finland holiday tests to cover Åland's Autonomy Day.
  • Chores

    • Added a new author entry to the contributors list.

Walkthrough

The pull request adds support for the Åland Islands to the holidays library. It updates documentation by adding a new author in AUTHORS.md and a new country entry in README.md. In the core library, a new file with the HolidaysAX class (and its aliases Aland, AX, and ALA) is introduced, along with necessary import and registry updates. Additionally, localization files for multiple languages and a suite of unit tests for the newly introduced holiday logic have been added. Minor refinements were also made to translation fallback logic and PO file generation.

Changes

File(s) Change Summary
AUTHORS.md, README.md Added new author entry in AUTHORS.md and updated README.md with a new "Aland" country entry (code AX, description, supported languages) to reflect expanded country code support.
holidays/countries/init.py, holidays/countries/aland_islands.py, holidays/registry.py Introduced Åland Islands support by adding the HolidaysAX class (with aliases Aland, AX, and ALA), updating imports, and extending the country registry with the new entry.
holidays/countries/finland.py Enhanced Finland class by adding subdivision metadata for Åland Islands and implementing Autonomy Day as a subdivision-specific holiday.
holidays/locale/en_US/LC_MESSAGES/AX.po, holidays/locale/fi/LC_MESSAGES/AX.po, holidays/locale/sv_FI/LC_MESSAGES/AX.po, holidays/locale/uk/LC_MESSAGES/AX.po Added new localization files (English, Finnish stub, Swedish stub, Ukrainian stub) for Åland Islands holidays.
holidays/locale/en_US/LC_MESSAGES/FI.po, holidays/locale/fi/LC_MESSAGES/FI.po, holidays/locale/sv_FI/LC_MESSAGES/FI.po, holidays/locale/uk/LC_MESSAGES/FI.po Updated Finnish, Swedish (Finland), English, and Ukrainian Finnish holiday locale files to include the new Åland's Autonomy Day holiday translation entries.
holidays/holiday_base.py Refined _init_translation method to better handle language fallback logic for translations.
scripts/l10n/generate_po_files.py Modified PO file generation to skip processing the Åland Islands ("AX") entity when generating .pot files.
tests/countries/test_aland_islands.py Added comprehensive unit tests for Åland Islands holidays, covering holiday presence, localization, and aliases.
tests/countries/test_finland.py Added test verifying Åland's Autonomy Day holiday for Finland subdivision "01" and updated localization tests to include this holiday.
tests/common.py Simplified assertLocalizedHolidays method to align test logic with production by removing redundant language checks.

Assessment against linked issues

Objective Addressed Explanation
Add Åland Islands holidays (#2424)

Possibly related PRs

Suggested reviewers

  • KJhellico
  • PPsyrius
  • arkid15r
✨ Finishing Touches
  • 📝 Generate Docstrings

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

Documentation and Community

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9f3936c and c504650.

📒 Files selected for processing (7)
  • AUTHORS.md (1 hunks)
  • README.md (2 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/countries/aland_islands.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/AX.po (1 hunks)
  • holidays/registry.py (1 hunks)
  • tests/countries/test_aland_Islands.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
holidays/countries/__init__.py (1)
holidays/countries/aland_islands.py (3)
  • AlandIslands (21-105)
  • AX (109-110)
  • ALA (112-113)
holidays/countries/aland_islands.py (4)
holidays/calendars/gregorian.py (2)
  • _get_all_sundays (92-95)
  • _timedelta (37-42)
holidays/groups/christian.py (2)
  • _add_epiphany_day (290-306)
  • _add_good_friday (308-317)
holidays/groups/international.py (2)
  • _add_new_years_day (126-134)
  • _add_labor_day (99-108)
holidays/holiday_base.py (2)
  • HolidayBase (57-1275)
  • _add_holiday (793-805)
🪛 Ruff (0.8.2)
holidays/countries/aland_islands.py

81-81: Blank line contains whitespace

Remove whitespace from blank line

(W293)


84-84: Blank line contains whitespace

Remove whitespace from blank line

(W293)

tests/countries/test_aland_Islands.py

1-1: Invalid module name: 'test_aland_Islands'

(N999)


23-23: Blank line contains whitespace

Remove whitespace from blank line

(W293)


79-79: Blank line contains whitespace

Remove whitespace from blank line

(W293)


110-110: Blank line contains whitespace

Remove whitespace from blank line

(W293)


113-113: Blank line contains whitespace

Remove whitespace from blank line

(W293)


167-167: Blank line contains whitespace

Remove whitespace from blank line

(W293)


169-169: Blank line contains whitespace

Remove whitespace from blank line

(W293)


189-189: Blank line contains whitespace

Remove whitespace from blank line

(W293)


231-231: Blank line contains whitespace

Remove whitespace from blank line

(W293)


302-302: Blank line contains whitespace

Remove whitespace from blank line

(W293)

🔇 Additional comments (12)
AUTHORS.md (1)

20-20: Contributor addition looks good.

The new author "Ary Hauffe Neto" has been properly added to the alphabetical list of contributors.

holidays/registry.py (1)

24-24: Entry correctly added to the registry.

The Åland Islands entry follows the established pattern with the class name, ISO alpha-2, and alpha-3 codes in the proper format and is inserted in the correct alphabetical position.

holidays/countries/__init__.py (1)

16-16: Import statement properly added.

The import for AlandIslands and its alternative references (AX, ALA) follows the module's import pattern and maintains alphabetical ordering.

README.md (1)

102-102: Country count correctly updated.

The number of supported country codes has been correctly incremented from 165 to 166 to reflect the addition of Åland Islands.

holidays/locale/en_US/LC_MESSAGES/AX.po (2)

15-28: LGTM! Well-structured PO file metadata.

The metadata section follows the standard gettext format with appropriate project information and encoding settings.


29-97: Holiday translations look good.

All holiday translations from Swedish to English are appropriately defined with descriptive comments. The translations are accurate and complete.

holidays/countries/aland_islands.py (3)

21-34: Implementation looks good with comprehensive documentation.

The class is well-documented with appropriate references. The class properties (country code, languages, categories) are correctly defined.


36-39: Constructor implementation is correct.

The initialization correctly calls parent class constructors in the appropriate order.


41-105: Holiday definitions are well-implemented.

The method correctly implements all relevant Åland Islands holidays with appropriate conditional logic for historical changes.

🧰 Tools
🪛 Ruff (0.8.2)

81-81: Blank line contains whitespace

Remove whitespace from blank line

(W293)


84-84: Blank line contains whitespace

Remove whitespace from blank line

(W293)

tests/countries/test_aland_Islands.py (3)

19-27: Test setup looks good.

The test class properly inherits from necessary base classes and sets up the test environment correctly.

🧰 Tools
🪛 Ruff (0.8.2)

23-23: Blank line contains whitespace

Remove whitespace from blank line

(W293)


29-186: Holiday tests are thorough and well-structured.

The individual holiday tests verify both specific dates and year ranges, providing good test coverage for all holidays.

🧰 Tools
🪛 Ruff (0.8.2)

79-79: Blank line contains whitespace

Remove whitespace from blank line

(W293)


110-110: Blank line contains whitespace

Remove whitespace from blank line

(W293)


113-113: Blank line contains whitespace

Remove whitespace from blank line

(W293)


167-167: Blank line contains whitespace

Remove whitespace from blank line

(W293)


169-169: Blank line contains whitespace

Remove whitespace from blank line

(W293)


200-340: Localization tests are comprehensive.

The tests for English, Thai, and Ukrainian translations verify the correct localization of holiday names.

🧰 Tools
🪛 Ruff (0.8.2)

231-231: Blank line contains whitespace

Remove whitespace from blank line

(W293)


302-302: Blank line contains whitespace

Remove whitespace from blank line

(W293)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (7)
README.md (1)

151-155: Consistency fix needed in language specification.

The new Åland Islands entry looks good, but the default language is listed as "sv" in lowercase while other parts of the table maintain this consistency, matching the implementation in AlandIslands class where default_language = "sv".

tests/countries/test_aland_Islands.py (4)

1-1: Rename file to follow Python naming conventions.

The filename uses mixed case (test_aland_Islands.py) which doesn't follow PEP 8 naming conventions. Python module names should be lowercase with underscores.

#!/bin/bash
# Show current file naming pattern for test files
ls tests/countries/test_*.py | head -5
🧰 Tools
🪛 Ruff (0.8.2)

1-1: Invalid module name: 'test_aland_Islands'

(N999)


23-23: Remove whitespace from blank lines.

There's extra whitespace in several blank lines throughout the file that should be removed.

🧰 Tools
🪛 Ruff (0.8.2)

23-23: Blank line contains whitespace

Remove whitespace from blank line

(W293)


56-57: Remove whitespace from blank lines.

There's extra whitespace in these blank lines that should be removed.


79-79: Remove whitespace from blank lines.

There's extra whitespace in this blank line that should be removed.

🧰 Tools
🪛 Ruff (0.8.2)

79-79: Blank line contains whitespace

Remove whitespace from blank line

(W293)

holidays/countries/aland_islands.py (2)

81-82: Remove whitespace from blank line.

There's whitespace in this blank line that should be removed.

🧰 Tools
🪛 Ruff (0.8.2)

81-81: Blank line contains whitespace

Remove whitespace from blank line

(W293)


84-84: Remove whitespace from blank line.

There's whitespace in this blank line that should be removed.

🧰 Tools
🪛 Ruff (0.8.2)

84-84: Blank line contains whitespace

Remove whitespace from blank line

(W293)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c504650 and 4fb9715.

📒 Files selected for processing (4)
  • README.md (2 hunks)
  • holidays/countries/aland_islands.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/AX.po (1 hunks)
  • tests/countries/test_aland_Islands.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/countries/test_aland_Islands.py (2)
tests/common.py (1)
  • assertHolidayName (195-199)
holidays/countries/aland_islands.py (2)
  • AlandIslands (21-105)
  • AX (109-110)
holidays/countries/aland_islands.py (3)
holidays/calendars/gregorian.py (2)
  • _get_all_sundays (92-95)
  • _timedelta (37-42)
holidays/groups/christian.py (6)
  • _add_epiphany_day (290-306)
  • _add_good_friday (308-317)
  • _add_easter_sunday (270-279)
  • _add_easter_monday (259-268)
  • _add_ascension_thursday (119-127)
  • _add_whit_sunday (443-453)
holidays/holiday_base.py (1)
  • _add_holiday (793-805)
🪛 Ruff (0.8.2)
tests/countries/test_aland_Islands.py

1-1: Invalid module name: 'test_aland_Islands'

(N999)


23-23: Blank line contains whitespace

Remove whitespace from blank line

(W293)


79-79: Blank line contains whitespace

Remove whitespace from blank line

(W293)

holidays/countries/aland_islands.py

81-81: Blank line contains whitespace

Remove whitespace from blank line

(W293)


84-84: Blank line contains whitespace

Remove whitespace from blank line

(W293)

🔇 Additional comments (7)
holidays/locale/en_US/LC_MESSAGES/AX.po (2)

13-14: Localization header now correctly references Åland Islands.

The header comment properly references "Åland Islands holidays" rather than Sweden, matching the purpose of this file.


29-98: Well-structured translations for all holiday names.

The translations from Swedish to English are comprehensive and correctly formatted with appropriate context comments.

tests/countries/test_aland_Islands.py (1)

61-71: Tests validate both fixed dates and conditional dates correctly.

Good test approach validating both regular dates and the special case for Finland's Independence Day from 1917 onward.

holidays/countries/aland_islands.py (4)

21-34: Well-structured class definition with appropriate metadata.

The AlandIslands class is well-defined with proper country code, language support, and documentation references.


57-87: Properly implemented conditional holidays based on historical dates.

The implementation correctly handles holidays that started in specific years:

  • May Day (from 1939)
  • Finnish Independence Day (from 1917)
  • Variation of Midsummer Eve (changed in 1953)
🧰 Tools
🪛 Ruff (0.8.2)

81-81: Blank line contains whitespace

Remove whitespace from blank line

(W293)


84-84: Blank line contains whitespace

Remove whitespace from blank line

(W293)


100-104: Good implementation for optional Sundays.

The code properly handles the inclusion of Sundays as holidays when the include_sundays flag is set, using the appropriate helper function.


105-111: Alias classes now have proper docstrings.

The alias classes AX and ALA now correctly include docstrings explaining they're alternative references to the Åland Islands holidays.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4fb9715 and c7b6974.

📒 Files selected for processing (2)
  • holidays/countries/aland_islands.py (1 hunks)
  • tests/countries/test_aland_islands.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
holidays/countries/aland_islands.py (3)
holidays/calendars/gregorian.py (2)
  • _get_all_sundays (92-95)
  • _timedelta (37-42)
holidays/groups/christian.py (7)
  • ChristianHolidays (22-463)
  • _add_epiphany_day (290-306)
  • _add_good_friday (308-317)
  • _add_easter_sunday (270-279)
  • _add_easter_monday (259-268)
  • _add_ascension_thursday (119-127)
  • _add_whit_sunday (443-453)
holidays/holiday_base.py (2)
  • HolidayBase (57-1275)
  • _add_holiday (793-805)
🔇 Additional comments (16)
holidays/countries/aland_islands.py (10)

1-12: The copyright header looks good.

Standard project copyright header is properly included.


13-19: Imports are well organized.

Necessary imports from the holidays package are correctly included, following the project's import structure.


21-35: Class definition and metadata are properly implemented.

The AlandIslands class extends the appropriate base classes and defines the correct metadata for the Åland Islands. Good job including references for the holiday information.


36-40: Constructor properly initializes parent classes.

The init method correctly initializes parent classes following the project's pattern.


41-66: Christian holidays implementation looks good.

The first part of the _populate_public_holidays method correctly implements standard holidays including New Year's Day, Epiphany, Good Friday, Easter, and Whit Sunday.


70-83: Midsummer implementation with conditional logic looks good.

The implementation correctly handles different date calculations for Midsummer Eve and Day based on the year, with a condition for years before/after 1953.


84-87: Finnish Independence Day conditional implementation is correct.

The code properly checks if the year is after 1917 before adding the Finnish Independence Day holiday.


88-105: Christmas holidays and Sunday handling implementation looks good.

The implementation of Christmas Eve, Christmas Day, Second Day of Christmas, New Year's Eve, and Sunday handling is correct and follows the project's patterns.


107-117: Alias classes with docstrings are properly implemented.

The AX and ALA alias classes are correctly defined with appropriate docstrings explaining their purpose as ISO code alternatives.


67-69:

❓ Verification inconclusive

Verify implementation of Autonomy Day method.

The code calls _add_holiday_jun_9 which isn't directly shown in the provided code snippets. Ensure this method exists in one of the parent classes or is implemented elsewhere.


🏁 Script executed:

#!/bin/bash
# Check if the _add_holiday_jun_9 method is defined in any file
rg -A 3 "_add_holiday_jun_9" --type py

Length of output: 1268


I'll run one more script to search for the actual definition of _add_holiday_jun_9 in the codebase.


🏁 Script executed:

#!/bin/bash
rg -n "def _add_holiday_jun_9" --type py

Length of output: 42


I'll run an additional script to search for any definitions matching _add_holiday_ to see if the method is defined dynamically or as part of a parent class.


🏁 Script executed:

#!/bin/bash
rg -n "def _add_holiday_" --type py

Length of output: 37


Autonomy Day Method Implementation Check

We verified that _add_holiday_jun_9 is referenced across several country modules (Aland Islands, Spain, and New Zealand) but couldn’t locate its definition within the immediate codebase. This suggests the method is expected to be implemented in a parent class or provided via a mixin/dynamic mechanism. Please confirm that the inheritance chain or dynamic assignment indeed defines _add_holiday_jun_9 so that Autonomy Day (and related holiday calculations) work as intended.

tests/countries/test_aland_islands.py (6)

25-35: Test class setup looks good.

The test class is properly set up with a holidays instance covering a wide range of years (1930-2050) and with Sundays included.


36-53: Fixed holidays test implementation looks comprehensive.

The test correctly verifies multiple fixed date holidays across a wide range of years and includes a test for the conditional May Day holiday (not observed before 1939).


54-85: Movable holidays test implementation looks good.

The test properly verifies movable Christian holidays for specific years and also checks that Good Friday is recognized throughout the test range.


86-90: Finnish Independence Day test is correctly implemented.

The test verifies that Independence Day is recognized from 1917 onwards but not before, matching the implementation in the main class.


91-99: Negative test cases look good.

The test correctly verifies that specific dates are not recognized as holidays.


36-99:

✅ Verification successful

Verify custom assertion methods.

The test uses custom assertion methods like assertHolidayName, assertNoHolidayName, and assertNoHoliday that aren't standard unittest methods. Ensure these are defined in a parent test class or helper.


🏁 Script executed:

#!/bin/bash
# Check for the implementation of custom assertion methods
rg -A 5 "def assert(Holiday|NoHoliday)" --type py tests/

Length of output: 2751


Custom assertion methods verified in helper file

We've confirmed that the custom assertion methods (assertHolidayName, assertNoHolidayName, and assertNoHoliday) used in tests/countries/test_aland_islands.py are indeed defined in the parent helper file tests/common.py. No further action is needed regarding these custom methods.

@KJhellico
Copy link
Collaborator

Since Åland Islands are an administrative subdivision of Finland, its holidays should be implemented similarly to the US overseas territories (Guam, Puerto Rico, American Samoa, etc.). That is, you need to add subdivisions to Finland (since it isn't currently included there), and implement Åland specific holidays (Autonomy Day, as I can see) in _populate_subdiv_XX_public_holidays().

@Arynelson
Copy link
Contributor Author

_populate_subdiv_XX_public_holidays()

ok I'll do it like this, thanks for the tip

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c7b6974 and c3488eb.

📒 Files selected for processing (5)
  • README.md (2 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/countries/aland_islands.py (1 hunks)
  • holidays/countries/finland.py (1 hunks)
  • tests/countries/test_aland_islands.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
holidays/countries/__init__.py (1)
holidays/countries/aland_islands.py (3)
  • Aland (19-42)
  • AX (45-48)
  • ALA (51-54)
🔇 Additional comments (14)
holidays/countries/finland.py (1)

39-39: Good addition of the subdivisions attribute.

The addition of the subdivisions attribute with Åland Islands (AX) is properly implemented and well-documented. This follows the pattern suggested in the PR comments to handle Åland similar to US overseas territories.

holidays/countries/__init__.py (1)

16-16: Import looks good.

The import for the Åland Islands classes is correctly placed alphabetically in the import list, following the existing pattern.

README.md (1)

102-102: Correctly updated country count.

The count of supported country codes has been properly updated from 165 to 166.

holidays/countries/aland_islands.py (5)

1-12: License and header information looks good.

The header with license, authors, and website information matches other files in the project.


19-31: Well-structured Aland class.

The class structure follows the project conventions with:

  • Clear docstrings and references
  • Proper country code "AX"
  • Appropriate supported categories
  • Empty subdivisions tuple (since Åland is a subdivision itself)
  • Start year of 1920 (when Åland received autonomy status)

This implementation correctly follows the pattern for adding a new territory.


33-36: Good implementation of unofficial holidays.

Setting self.subdiv = "AX" before calling the parent method ensures proper localization of holiday names.


37-43: Correctly added Autonomy Day.

The implementation adds Autonomy Day (June 9th) as a public holiday for Åland Islands while inheriting all Finnish holidays. This is exactly the right approach for handling territory-specific holidays.


45-54: Alias classes properly implemented.

The AX and ALA alias classes follow the standard pattern used throughout the library and include helpful docstrings explaining they are alternative references.

tests/countries/test_aland_islands.py (6)

18-23: Test setup follows good practices

The test class setup is efficient, creating a single holidays instance for the entire test suite that covers a wide range of years (1930-2050).


25-41: Fixed date holidays are well-implemented with historical accuracy

The test correctly verifies that Autonomy Day ("Självstyrelsedagen") is recognized from 1920 onward, which aligns with historical facts about when Åland gained its autonomous status. Similarly, the test correctly handles "Första maj" (May Day) starting from 1939.


42-73: Movable holidays tests are comprehensive

Good implementation of tests for holidays with variable dates. The specific test cases for years 2019-2024 provide concrete validation, while the range check ensures the holiday recognition works across all years.


74-78: Independence Day test is historically accurate

The test correctly verifies Finland's Independence Day from 1917 onward and confirms it's not recognized before that year, which aligns with Finland's history.


79-86: Non-holiday test looks good

The test properly verifies that specific dates are not recognized as holidays.


1-87:

❓ Verification inconclusive

Consider the Åland implementation structure

Based on the PR comments, there's a suggestion to implement Åland Islands as a subdivision of Finland rather than a separate country. The current test file treats Åland as a separate entity. Consider whether this implementation aligns with the project's structural recommendations.


🏁 Script executed:

#!/bin/bash
# Check how other subdivisions are implemented in the codebase

# Look for subdiv pattern usage in existing files
echo "Checking for subdivision patterns in existing files..."
rg -l "populate_subdiv" --type py

# Look for any examples of U.S. territories implementation
echo "Checking for U.S. territories implementation examples..."
rg -l "American Samoa|Guam|Puerto Rico" --type py

# Check Finland implementation for subdivision support
echo "Checking Finland implementation..."
fd -t f finland holidays/

Length of output: 1596


Action Required: Confirm Åland Islands Structure

The current tests treat Åland Islands as an independent country. However, as suggested in the PR discussion, please verify whether Åland Islands should instead be implemented as a subdivision of Finland for consistency with the project’s design. Notably:

  • Other subdivisions in the project use a similar pattern (e.g., via populate_subdiv) to integrate with their parent country (see examples in files like holidays/countries/united_states.py).
  • The Finland implementation (located in holidays/countries/finland.py) doesn’t currently incorporate Åland Islands as a subdivision.
  • Please review the related PR comments and structural guidelines to decide if this implementation needs to be revised.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Ary Hauffe <[email protected]>
Arynelson and others added 4 commits April 17, 2025 22:13
Co-authored-by: Panpakorn Siripanich <[email protected]>
Signed-off-by: Ary Hauffe <[email protected]>
Co-authored-by: Panpakorn Siripanich <[email protected]>
Signed-off-by: Ary Hauffe <[email protected]>
Co-authored-by: Panpakorn Siripanich <[email protected]>
Signed-off-by: Ary Hauffe <[email protected]>
Co-authored-by: Panpakorn Siripanich <[email protected]>
Signed-off-by: Ary Hauffe <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
holidays/countries/aland_islands.py (1)

52-56: 🧹 Nitpick (assertive)

Remove docstring for alias class.

According to team guidelines, docstrings for 3-letter code assignments should be removed.

 class ALA(Aland):
-    """Alternative name for the Åland Islands holidays (ISO 3166-1 alpha-3 code)."""
-
     pass
♻️ Duplicate comments (7)
holidays/countries/aland_islands.py (6)

35-36: ⚠️ Potential issue

Use correct subdivision code.

Finland uses "01" as the subdivision code for Åland Islands according to ISO 3166-2:FI.

-        self.subdiv = "AX"
+        self.subdiv = "01"

39-40: ⚠️ Potential issue

Use correct subdivision code.

Finland uses "01" as the subdivision code for Åland Islands according to ISO 3166-2:FI.

-        self.subdiv = "AX"
+        self.subdiv = "01"

31-32: 🛠️ Refactor suggestion

Update subdivision settings and start year.

According to ISO 3166-2:FI, the subdivision code for Åland is "01", and the autonomy was fully established in 1921.

-    subdivisions = ()
-    start_year = 1920
+    subdivisions = ()  # Override Finland subdivisions.
+    subdivisions_aliases = {}  # Override Finland subdivisions aliases.
+    # Aland Islands got its autonomy on May 7th, 1920.
+    start_year = 1921

42-43: ⚠️ Potential issue

Add year restriction and proper comment for Autonomy Day.

Autonomy Day wasn't observed as a holiday until at least 1993, and the comment should end with a period.

-        # Autonomy Day
-        self._add_holiday_jun_9(tr("Självstyrelsedagen"))
+        if self._year >= 1993:
+            # Autonomy Day.
+            self._add_holiday_jun_9(tr("Självstyrelsedagen"))

46-50: 🧹 Nitpick (assertive)

Remove docstring for alias class.

According to team guidelines, docstrings for 2-letter code assignments should be removed.

 class AX(Aland):
-    """Alternative name for the Åland Islands holidays (ISO 3166-1 alpha-2 code)."""
-
     pass

22-25: 🧹 Nitpick (assertive)

URL references need angle brackets.

Update the reference URLs to follow the project's format style:

-    References:
-        * https://en.wikipedia.org/wiki/Public_holidays_in_%C3%85land
-        * https://date.nager.at/PublicHoliday/%C3%85land-Islands/2025
-        * https://www.bank-holidays.com/country/Aland-Islands_194.htm
+    References:
+        * <https://en.wikipedia.org/wiki/Public_holidays_in_%C3%85land>
+        * <https://en.wikipedia.org/wiki/%C3%85land%27s_Autonomy_Day>
+        * <https://date.nager.at/PublicHoliday/%C3%85land-Islands/2025>
+        * <https://www.bank-holidays.com/country/Aland-Islands_194.htm>
holidays/locale/en_US/LC_MESSAGES/AX.po (1)

22-22: 🧹 Nitpick (assertive)

Update translator information.

Replace the placeholder with your actual information:

-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Last-Translator: Ary Hauffe Neto <[email protected]>\n"
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1ae5eb5 and 8e118fc.

📒 Files selected for processing (2)
  • holidays/countries/aland_islands.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/AX.po (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
holidays/locale/en_US/LC_MESSAGES/AX.po (2)
Learnt from: PPsyrius
PR: vacanza/holidays#2437
File: holidays/locale/dz_BT/LC_MESSAGES/BT.po:0-0
Timestamp: 2025-04-06T14:52:35.679Z
Learning: When suggesting changes to .po files in the holidays project, follow the standardized header format:
- Default language format: "# [COUNTRY-NAME-NORMAL] holidays. #"
- Non-default language format: "# [COUNTRY-NAME-NORMAL] holidays [LANGUAGE-CODE] localization. #"
For example, for Bhutan in Dzongkha, use "# Bhutan holidays dz_BT localization. #"
Learnt from: PPsyrius
PR: vacanza/holidays#2437
File: holidays/locale/dz_BT/LC_MESSAGES/BT.po:12-12
Timestamp: 2025-04-06T14:44:59.785Z
Learning: Use standardized .po file headers for localization files in the holidays project:
- Default language format: "# [COUNTRY-NAME-NORMAL] holidays. #"
- Other languages format: "# [COUNTRY-NAME-NORMAL] holidays [LANGUAGE-CODE] localization. #"
holidays/countries/aland_islands.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2398
File: holidays/countries/guinea.py:73-77
Timestamp: 2025-04-03T12:36:41.201Z
Learning: In the Holidays library, comments explaining year restrictions for holidays should be placed above the year check conditional statement, not inside it. Example format:
```python
# reason why goes here
if start_year <= self._year <= end_year:
    # Holiday name
    self._add_holiday_function(tr("Holiday Name"))

</details>

</details><details>
<summary>🧬 Code Graph Analysis (1)</summary>

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

<details>
<summary>holidays/countries/finland.py (3)</summary>

* `Finland` (21-185)
* `_populate_unofficial_holidays` (110-185)
* `_populate_public_holidays` (47-108)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (1)</summary><blockquote>

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

`32-34`: **Additional localization files needed.**

With `parent_entity = Finland` in `aland_islands.py`, we only need to add the new Autonomy Day entry for each language. Please create additional localization files for:
- Finnish (fi)
- Swedish (sv_FI)
- Ukrainian (uk)

These are the supported languages for Finland as defined in `finland.py`.

</details>

</blockquote></details>

</details>

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

Arynelson and others added 2 commits April 17, 2025 22:19
Co-authored-by: Panpakorn Siripanich <[email protected]>
Signed-off-by: Ary Hauffe <[email protected]>
Co-authored-by: Panpakorn Siripanich <[email protected]>
Signed-off-by: Ary Hauffe <[email protected]>
@arkid15r
Copy link
Collaborator

Please check the code conflicts too.

@PPsyrius
Copy link
Collaborator

PPsyrius commented Apr 21, 2025

@Arynelson I've created a suggestion PR to help sort out all remaining code review comments - although you'll still need to resolve merge conflicts with dev branch yourself later before this is up for merging.

@Arynelson
Copy link
Contributor Author

ok @PPsyrius , i will work on it

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (2)
holidays/locale/fi/LC_MESSAGES/AX.po (1)

1-28: 💡 Verification agent

🧩 Analysis chain

Finnish localization stub is correctly structured

The Finnish localization stub file follows the project's standard format with proper metadata headers. As recommended in the PR comments, you're correctly implementing Aland Islands as a subdivision of Finland with its own localization files.


🏁 Script executed:

#!/bin/bash
# Verify that Finland has been updated to include Aland Islands as a subdivision

# Check Finland implementation for subdivisions section
rg -n "subdivisions\s*=\s*\(" holidays/countries/finland.py

# Check if Autonomy Day holiday is implemented in Finland
rg -A 5 "Autonomy Day" holidays/countries/finland.py

Length of output: 255


Missing Åland Islands subdivision in Finland class

It looks like the subdivisions tuple wasn’t added to holidays/countries/finland.py, so although Autonomy Day is included, the Åland Islands isn’t registered as a subdivision. Please update the Finland class accordingly:

• File: holidays/countries/finland.py

 class Finland:
+    subdivisions = (
+        ("AX", "Åland Islands"),
+    )
 
  # Åland's Autonomy Day.
  self._add_holiday_jun_9(tr("Ahvenanmaan itsehallintopäivä"))
holidays/countries/aland_islands.py (1)

51-61: 🧹 Nitpick (assertive)

Consider adding docstrings to alias classes.

The alias classes would benefit from brief docstrings explaining their purpose.

 class Aland(HolidaysAX):
+    """Alternative name for the Åland Islands holidays."""
     pass


 class AX(HolidaysAX):
+    """ISO 3166-1 alpha-2 code for the Åland Islands holidays."""
     pass


 class ALA(HolidaysAX):
+    """ISO 3166-1 alpha-3 code for the Åland Islands holidays."""
     pass
♻️ Duplicate comments (2)
holidays/locale/en_US/LC_MESSAGES/AX.po (1)

1-28: ⚠️ Potential issue

Missing translation for Åland's Autonomy Day.

The file structure is correct, but it's missing the required translation for "Självstyrelsedagen" that should be present based on other locale files.

Add the following translation to complete the file:

+#. Autonomy Day.
+msgid "Självstyrelsedagen"
+msgstr "Autonomy Day"
holidays/countries/aland_islands.py (1)

27-28: 🧹 Nitpick (assertive)

URL encoding needed for special characters.

The URLs in the references section contain unencoded special characters ('Å') which might cause issues in some contexts. Consider using URL-encoded versions.

-        * <https://en.wikipedia.org/wiki/Public_holidays_in_Åland>
-        * <https://date.nager.at/PublicHoliday/Åland-Islands/2025>
+        * <https://en.wikipedia.org/wiki/Public_holidays_in_%C3%85land>
+        * <https://date.nager.at/PublicHoliday/%C3%85land-Islands/2025>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8188a56 and c8b7274.

📒 Files selected for processing (19)
  • AUTHORS.md (1 hunks)
  • README.md (3 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/countries/aland_islands.py (1 hunks)
  • holidays/countries/finland.py (2 hunks)
  • holidays/holiday_base.py (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/AX.po (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/FI.po (2 hunks)
  • holidays/locale/fi/LC_MESSAGES/AX.po (1 hunks)
  • holidays/locale/fi/LC_MESSAGES/FI.po (2 hunks)
  • holidays/locale/sv_FI/LC_MESSAGES/AX.po (1 hunks)
  • holidays/locale/sv_FI/LC_MESSAGES/FI.po (2 hunks)
  • holidays/locale/uk/LC_MESSAGES/AX.po (1 hunks)
  • holidays/locale/uk/LC_MESSAGES/FI.po (2 hunks)
  • holidays/registry.py (1 hunks)
  • scripts/l10n/generate_po_files.py (1 hunks)
  • tests/common.py (1 hunks)
  • tests/countries/test_aland_islands.py (1 hunks)
  • tests/countries/test_finland.py (5 hunks)
🧰 Additional context used
🧠 Learnings (4)
holidays/locale/en_US/LC_MESSAGES/AX.po (3)
Learnt from: PPsyrius
PR: vacanza/holidays#2437
File: holidays/locale/dz_BT/LC_MESSAGES/BT.po:0-0
Timestamp: 2025-04-06T14:52:35.679Z
Learning: When suggesting changes to .po files in the holidays project, follow the standardized header format:
- Default language format: "# [COUNTRY-NAME-NORMAL] holidays. #"
- Non-default language format: "# [COUNTRY-NAME-NORMAL] holidays [LANGUAGE-CODE] localization. #"
For example, for Bhutan in Dzongkha, use "# Bhutan holidays dz_BT localization. #"
Learnt from: PPsyrius
PR: vacanza/holidays#2437
File: holidays/locale/dz_BT/LC_MESSAGES/BT.po:12-12
Timestamp: 2025-04-06T14:44:59.785Z
Learning: Use standardized .po file headers for localization files in the holidays project:
- Default language format: "# [COUNTRY-NAME-NORMAL] holidays. #"
- Other languages format: "# [COUNTRY-NAME-NORMAL] holidays [LANGUAGE-CODE] localization. #"
Learnt from: KJhellico
PR: vacanza/holidays#2259
File: holidays/locale/en_IN/LC_MESSAGES/IN.po:30-299
Timestamp: 2025-03-05T17:51:00.633Z
Learning: In the Holidays project, .po files for a country's default locale use empty msgstr fields as a standard convention.
tests/common.py (1)
Learnt from: KJhellico
PR: vacanza/holidays#2398
File: tests/countries/test_guinea.py:237-239
Timestamp: 2025-04-02T18:38:35.164Z
Learning: In the vacanza/holidays project, the method assertLocalizedHolidays in country test files should be called with positional parameters rather than named parameters to maintain consistency with the rest of the codebase.
holidays/countries/aland_islands.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2398
File: holidays/countries/guinea.py:73-77
Timestamp: 2025-04-03T12:36:41.201Z
Learning: In the Holidays library, comments explaining year restrictions for holidays should be placed above the year check conditional statement, not inside it. Example format:
```python
# reason why goes here
if start_year <= self._year <= end_year:
    # Holiday name
    self._add_holiday_function(tr("Holiday Name"))

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

Learnt from: KJhellico
PR: #2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions.


Learnt from: KJhellico
PR: #2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions to enhance code readability by clearly separating high-level components.


</details>

</details><details>
<summary>🧬 Code Graph Analysis (3)</summary>

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

<details>
<summary>holidays/countries/aland_islands.py (4)</summary>

* `Aland` (51-52)
* `AX` (55-56)
* `ALA` (59-60)
* `HolidaysAX` (17-48)

</details>

</blockquote></details>
<details>
<summary>holidays/countries/finland.py (2)</summary><blockquote>

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

* `_populate_subdiv_01_public_holidays` (247-260)

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

* `_populate_subdiv_01_public_holidays` (190-192)

</details>

</blockquote></details>
<details>
<summary>tests/countries/test_finland.py (3)</summary><blockquote>

<details>
<summary>tests/countries/test_aland_islands.py (1)</summary>

* `test_alands_autonomy_day` (32-35)

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

* `Finland` (21-196)

</details>
<details>
<summary>tests/common.py (2)</summary>

* `assertHolidayName` (195-199)
* `assertNoHolidayName` (273-275)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (32)</summary><blockquote>

<details>
<summary>AUTHORS.md (1)</summary>

`21-23`: **Author entry is correctly placed.** “Ary Hauffe Neto” appears in proper lexicographical order between “Artem Tserekh” and “Bailey Thompson.” Nice work keeping the list sorted!

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

`16-16`: **Import added properly in alphabetical order**

The Aland Islands import is correctly added in alphabetical order, consistent with the file's organization.

</details>
<details>
<summary>holidays/locale/sv_FI/LC_MESSAGES/AX.po (1)</summary>

`1-28`: <details>
<summary>✅ Verification successful</summary>

**Swedish (Finland) localization stub is properly configured**

This stub correctly sets up Swedish (Finland) localization support for Aland Islands holidays. The Language field is properly set to `sv_FI` and all required metadata is present.


---

🏁 Script executed:

```shell
#!/bin/bash
# Check if sv_FI is defined as a supported language in the Aland Islands implementation

rg -n "supported_languages" holidays/countries/aland_islands.py

# Check if sv_FI is set as the default language
rg -n "default_language\s*=\s*\"sv_FI\"" holidays/countries/aland_islands.py

Length of output: 234


All set: Swedish (Finland) localization verified for Åland Islands

  • holidays/locale/sv_FI/LC_MESSAGES/AX.po has the correct metadata and language code.
  • holidays/countries/aland_islands.py defines
    • default_language = "sv_FI" (line 34)
    • "sv_FI" in supported_languages (line 35)
tests/common.py (1)

337-338: Good simplification of the localization testing logic.

The change properly aligns the test helper with production code's language handling, removing redundant calls and simplifying the flow.

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

1-28: LGTM - Ukrainian localization stub is correctly formatted.

The file follows the project's .po file structure with proper headers and metadata.

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

164-167: Correctly added Åland's Autonomy Day Ukrainian translation.

The translation for Åland's Autonomy Day is properly formatted and placed at the end of the file.

holidays/registry.py (1)

24-24: Entry looks good.

The Åland Islands entry is correctly structured with the proper class name, ISO codes, and alias. It's also placed in alphabetical order within the COUNTRIES dictionary.

holidays/locale/en_US/LC_MESSAGES/FI.po (2)

17-17: Metadata updates look good.

The version number, revision date, and generator information have been correctly updated.

Also applies to: 19-19, 27-27


165-167: Properly added translation for Åland's Autonomy Day.

Good work adding the English translation for the Åland's Autonomy Day holiday. The comment and message format follows the established pattern in the file.

holidays/locale/sv_FI/LC_MESSAGES/FI.po (2)

17-17: Metadata updates look good.

The version number, revision date, and generator information have been correctly updated.

Also applies to: 19-19, 27-27


165-167: Properly added Swedish translation for Åland's Autonomy Day.

Good addition of the Swedish translation "Ålands självstyrelsedag" for Åland's Autonomy Day. The format follows the established pattern in the file.

holidays/locale/fi/LC_MESSAGES/FI.po (2)

17-17: Metadata updates look good.

The version number, revision date, and generator information have been correctly updated.

Also applies to: 19-19, 27-27


165-167: Properly added placeholder for Åland's Autonomy Day.

The Finnish entry for "Ahvenanmaan itsehallintopäivä" has been correctly added with an empty msgstr, which is the expected format for the native language file.

README.md (2)

151-156: Excellent addition of Åland Islands entry!

The newly added entry is properly structured and includes all the necessary information: ISO code (AX), loading instructions, supported languages (with sv_FI correctly marked as default), and the UNOFFICIAL category. This aligns perfectly with the PR objective to introduce holiday support for the Åland Islands.


524-524: Good subdivision addition for Finland!

The Finland entry now correctly includes the Åland Islands as subdivision "01" with proper alternative names in Finnish, Swedish, and the common name. This provides users with the flexibility to load Åland holidays either as a standalone country or as a Finland subdivision.

tests/countries/test_finland.py (5)

298-305: Great test implementation for Åland's Autonomy Day!

This test thoroughly verifies that:

  1. Åland's Autonomy Day is present for years 1993-2049 when subdivision "01" is specified
  2. The holiday doesn't exist before 1993 in the same subdivision
  3. The holiday doesn't exist at all without a subdivision specified

The test properly creates a Finland object with subdivision "01" and uses appropriate assertion methods to validate the holiday's presence under correct conditions.


388-388: Appropriate localization verification for Finnish!

The test now verifies that the Autonomy Day appears with the correct Finnish name ("Ahvenanmaan itsehallintopäivä") in the default localization test. This ensures the holiday name is correctly translated in the primary language.


428-428: Good English localization test!

The test verifies the English translation "Åland's Autonomy Day" is correctly used when the en_US locale is specified. This ensures proper internationalization support.


468-468: Proper Ukrainian localization test!

The test confirms the Ukrainian translation "День автономії Аландських островів" is correctly used when the uk locale is specified.


508-508: Correct Swedish localization test!

The Swedish translation "Ålands självstyrelsedag" is properly tested when using the sv_FI locale, which is important as Swedish is the primary language in Åland.

holidays/holiday_base.py (1)

763-768: Improved language selection logic!

The refactored code makes the language selection more robust by:

  1. Prioritizing user-specified language when valid
  2. Falling back to the default language when necessary
  3. Setting languages to None as a last resort

This improvement ensures more consistent behavior when dealing with multilingual holiday names, especially for regions like Åland where multiple languages are supported.

holidays/countries/finland.py (3)

33-33: Good docstring enhancement!

Adding the reference link to Åland's Autonomy Day in Wikipedia improves the documentation and provides context for the added holiday.


40-45: Well implemented subdivision support!

The implementation correctly:

  1. Defines "01" as the subdivision code for Åland Islands
  2. Provides aliases in Finnish ("Ahvenanmaan maakunta"), Swedish ("Landskapet Åland"), and the common name ("Åland")

This follows the project's pattern for defining subdivisions and their aliases, allowing users to refer to Åland using various names.


193-196: Correctly implemented Åland-specific holiday!

The _populate_subdiv_01_public_holidays method properly:

  1. Checks for years >= 1993 (when the holiday was established)
  2. Adds Åland's Autonomy Day on June 9
  3. Uses the translation function to support multiple languages

This implementation follows the project's conventions for subdivision-specific holidays and aligns with the requirements specified in the PR comments to handle Åland as a subdivision of Finland.

holidays/countries/aland_islands.py (2)

32-33: Implementation follows the correct pattern for territories.

Setting country = "AX" and parent_entity = Finland correctly follows the pattern used for autonomous territories. This matches the guidance to implement Åland Islands as a subdivision of Finland similar to U.S. overseas territories.


42-48: Implementation correctly uses Finland's subdivision approach.

The code properly sets the subdivision code to "01" before calling the parent methods, ensuring that Åland Islands' holidays are defined as a subdivision of Finland. This aligns with the ISO 3166-2:FI standard and the PR comments recommending this approach.

tests/countries/test_aland_islands.py (6)

32-35: Good test coverage for Autonomy Day.

Excellent test for Åland's Autonomy Day, verifying both its presence from 1993 onward and its absence before that year. This aligns with historical accuracy about when this holiday was officially recognized.


37-74: Comprehensive default localization testing.

The default localization test (Swedish) thoroughly covers all holidays, including the Åland-specific Autonomy Day. This is important since Swedish is the predominant language in Åland Islands.


76-114: Well-structured English localization tests.

The English (US) localization tests follow the same pattern as the default tests, providing consistent verification of holiday names. Good inclusion of Åland's Autonomy Day with proper apostrophe in "Åland's".


116-154: Finnish localization tests provide good coverage.

The Finnish localization tests maintain the consistent pattern established in earlier tests and include the correct Finnish name for Åland's Autonomy Day.


156-194: Ukrainian localization tests complete the language coverage.

The Ukrainian localization tests round out the language support testing, maintaining the same comprehensive approach as the other language tests.


20-24: 🧹 Nitpick (assertive)

Consider adding edge case tests around the start year.

While you test that no holidays exist for 1920, consider adding specific tests for 1921 to verify that holidays are correctly populated in the first year of Åland's autonomy.

def test_first_year_holidays(self):
    holidays_1921 = HolidaysAX(years=1921)
    self.assertIn("1921-01-01", holidays_1921)  # New Year's Day
    # Add other expected holidays for 1921
⛔ Skipped due to learnings
Learnt from: PPsyrius
PR: vacanza/holidays#2416
File: tests/countries/test_turkmenistan.py:52-64
Timestamp: 2025-04-05T04:47:27.213Z
Learning: For holiday tests in the vacanza/holidays project, structure tests by individual holidays rather than by years. Each test method should focus on a specific holiday and test it across multiple years (from start_year through 2050) using helper methods like `assertHolidayName`. For fixed holidays, use generators like `(f"{year}-01-01" for year in range(1991, 2051))`. For movable holidays, specify individual dates for specific years followed by a range check.
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.

super()._populate_public_holidays()


class Aland(HolidaysAX):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
class Aland(HolidaysAX):
class AlandIslands(HolidaysAX):

According to ISO name.



class HolidaysAX(Finland):
"""Aland Islands holidays.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"""Aland Islands holidays.
"""Åland Islands holidays.

@KJhellico KJhellico changed the title Add Aland Islands Add Åland Islands holidays Apr 23, 2025
@KJhellico
Copy link
Collaborator

@Arynelson, you have other branch aland-island in your repo, that is more up-to-date than this one - Aland-Island. Isn't this some kind of typo?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
scripts/l10n/generate_po_files.py (1)

72-74: 🧹 Nitpick (assertive)

Consider adding more context about the lingva issue.

The comment indicates this is a temporary skip for Åland Islands, but it would be helpful to add more details about the specific issue or reference a tracking issue number.

-            # [Temp] Aland Islands skip until we sort out lingva later.
+            # [Temp] Aland Islands skip until we sort out lingva later.
+            # TODO: Remove this skip once Lingva handles l10n stubs for Åland Islands.
tests/countries/test_aland_islands.py (1)

15-15: 🧹 Nitpick (assertive)

Simplify imports by removing unused constant.

The UNOFFICIAL constant is imported but never used in the test class. Clean up the imports by removing this unused import.

-from holidays.constants import UNOFFICIAL
🧰 Tools
🪛 Ruff (0.8.2)

15-15: holidays.constants.UNOFFICIAL imported but unused

Remove unused import: holidays.constants.UNOFFICIAL

(F401)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c8b7274 and bee78d9.

📒 Files selected for processing (9)
  • AUTHORS.md (1 hunks)
  • README.md (2 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/holiday_base.py (1 hunks)
  • holidays/registry.py (1 hunks)
  • scripts/l10n/generate_po_files.py (1 hunks)
  • tests/common.py (1 hunks)
  • tests/countries/test_aland_islands.py (1 hunks)
  • tests/countries/test_finland.py (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
tests/common.py (1)
Learnt from: KJhellico
PR: vacanza/holidays#2398
File: tests/countries/test_guinea.py:237-239
Timestamp: 2025-04-02T18:38:35.164Z
Learning: In the vacanza/holidays project, the method assertLocalizedHolidays in country test files should be called with positional parameters rather than named parameters to maintain consistency with the rest of the codebase.
tests/countries/test_aland_islands.py (2)
Learnt from: KJhellico
PR: vacanza/holidays#2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions.
Learnt from: KJhellico
PR: vacanza/holidays#2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions to enhance code readability by clearly separating high-level components.
🧬 Code Graph Analysis (2)
holidays/countries/__init__.py (1)
holidays/countries/aland_islands.py (4)
  • Aland (51-52)
  • AX (55-56)
  • ALA (59-60)
  • HolidaysAX (17-48)
tests/countries/test_finland.py (3)
tests/countries/test_aland_islands.py (1)
  • test_alands_autonomy_day (31-34)
holidays/countries/finland.py (1)
  • Finland (21-196)
tests/common.py (2)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
🪛 Ruff (0.8.2)
tests/countries/test_aland_islands.py

15-15: holidays.constants.UNOFFICIAL imported but unused

Remove unused import: holidays.constants.UNOFFICIAL

(F401)

🔇 Additional comments (11)
AUTHORS.md (1)

21-21: LGTM! Author added in correct alphabetical position.

The new author entry has been properly placed in alphabetical order between "Artem Tserekh" and "Bailey Thompson".

holidays/countries/__init__.py (1)

16-16: LGTM! Import follows established pattern.

The import for Åland Islands holiday classes follows the same pattern as other country imports, bringing in the main class and its aliases.

tests/common.py (1)

337-338: LGTM! Simplified method aligns with production logic.

Good simplification of the assertLocalizedHolidays method. The comment clearly explains that this change is intended to match the logic used in production.

holidays/registry.py (1)

24-24: Correct addition of Åland Islands to country registry

The Åland Islands entry follows the proper format with appropriate country codes (AX as ISO alpha-2 and ALA as ISO alpha-3) and is correctly alphabetized in the list.

README.md (2)

151-156: Properly documented Åland Islands support

The Åland Islands entry is correctly added with:

  • Proper ISO code "AX"
  • Clear indication of Finland subdivision relationship (01)
  • Appropriate language support with sv_FI as default
  • Correct UNOFFICIAL category specification

524-524: Good Finland entry update to include Åland subdivision

The Finland entry is correctly updated to include Åland as a region with appropriate names in Finnish, Swedish and English.

tests/countries/test_finland.py (2)

298-305: Well-structured test for Åland's Autonomy Day

The test properly verifies that:

  1. Åland's Autonomy Day is present for subdivision "01" (Åland) from 1993 onward
  2. The holiday is not present before 1993
  3. The holiday is not present when no subdivision is specified

This effectively tests the implementation in the Finland class.


388-388: Consistent localization test updates for Åland's Autonomy Day

The holiday has been appropriately added to all relevant localization tests with proper translations in Finnish, English, and Swedish.

Also applies to: 428-428, 508-508

holidays/holiday_base.py (1)

789-794: Improved translation initialization logic

The updated code enhances the language selection mechanism for translations by:

  1. Prioritizing user-specified language if supported
  2. Falling back to default language when available
  3. Using None as last resort

This refinement ensures correct language fallback behavior when translating holiday names, which will benefit the new Åland Islands implementation.

tests/countries/test_aland_islands.py (2)

31-35: The test for Åland's Autonomy Day looks good.

The test correctly verifies that Autonomy Day exists from 1993 onwards and doesn't exist before that year, matching the historical facts of when this holiday was established.


36-73: Comprehensive localization tests cover all needed languages.

The localization tests thoroughly cover all required languages (default Swedish, English US, Finnish, and Ukrainian) with appropriate holiday names for each language. The test data is well-structured and includes Åland's Autonomy Day in all languages.

Also applies to: 75-113, 115-153, 155-193

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
scripts/l10n/generate_po_files.py (1)

72-74: 🧹 Nitpick (assertive)

Consider updating the TODO comment with more details.

This temporary skip for Åland Islands lacks specific information about why it's needed. Based on previous review discussions, this appears to be related to Lingva handling of localization stubs.

-            # [Temp] Aland Islands skip until we sort out lingva later.
+            # [Temp] Skip Åland Islands due to Lingva handling limitations with l10n stubs.
+            # TODO: This can be removed after merging PR #2470 and resolving merge conflicts.
             if entity_code == "AX":
                 continue
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c8b7274 and bee78d9.

📒 Files selected for processing (9)
  • AUTHORS.md (1 hunks)
  • README.md (2 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/holiday_base.py (1 hunks)
  • holidays/registry.py (1 hunks)
  • scripts/l10n/generate_po_files.py (1 hunks)
  • tests/common.py (1 hunks)
  • tests/countries/test_aland_islands.py (1 hunks)
  • tests/countries/test_finland.py (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
tests/common.py (1)
Learnt from: KJhellico
PR: vacanza/holidays#2398
File: tests/countries/test_guinea.py:237-239
Timestamp: 2025-04-02T18:38:35.164Z
Learning: In the vacanza/holidays project, the method assertLocalizedHolidays in country test files should be called with positional parameters rather than named parameters to maintain consistency with the rest of the codebase.
tests/countries/test_aland_islands.py (2)
Learnt from: KJhellico
PR: vacanza/holidays#2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions.
Learnt from: KJhellico
PR: vacanza/holidays#2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions to enhance code readability by clearly separating high-level components.
🧬 Code Graph Analysis (2)
holidays/countries/__init__.py (1)
holidays/countries/aland_islands.py (4)
  • Aland (51-52)
  • AX (55-56)
  • ALA (59-60)
  • HolidaysAX (17-48)
tests/countries/test_finland.py (3)
tests/countries/test_aland_islands.py (1)
  • test_alands_autonomy_day (31-34)
holidays/countries/finland.py (1)
  • Finland (21-196)
tests/common.py (2)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
🪛 Ruff (0.8.2)
tests/countries/test_aland_islands.py

15-15: holidays.constants.UNOFFICIAL imported but unused

Remove unused import: holidays.constants.UNOFFICIAL

(F401)

🔇 Additional comments (20)
AUTHORS.md (1)

21-21: Entry is properly sorted

The new author "Ary Hauffe Neto" is correctly placed between "Artem Tserekh" and "Bailey Thompson" in lexicographical order.

holidays/countries/__init__.py (1)

16-16: Import added correctly.

The import for Åland Islands classes follows the same pattern as other country imports, with both the main class and its aliases imported.

tests/common.py (1)

337-338: Simplified test behavior to match production logic.

This change aligns the test behavior with the updated translation handling logic. The method now only checks against the provided language parameter rather than testing with invalid language scenarios.

holidays/registry.py (1)

24-24: Registry entry correctly implemented.

The Åland Islands entry follows the established format with the key matching the module name and the tuple containing appropriate class name, country codes, and holiday class.

README.md (2)

151-156: Appropriate Åland Islands entry added to the country table.

The new entry for Åland Islands is well-structured with the correct ISO code, loading instructions, supported languages, and category information. The entry specifies it can be loaded as Finland's subdivision 01 and properly highlights sv_FI as the default language.


524-524: Finland's entry correctly updated with Åland subdivision information.

The Finland entry has been updated to include its subdivision information for Åland (01), which properly connects the two entries and provides consistency in the documentation.

holidays/holiday_base.py (1)

789-794: Improved language selection logic for translations.

The updated language selection logic in _init_translation improves the fallback mechanism by creating a clearer hierarchy:

  1. First tries user-specified language if supported
  2. Falls back to the entity's default language if set
  3. Otherwise uses None (system default)

This enhancement provides better support for localized holiday names, particularly for entities like Åland Islands that have specific language preferences.

tests/countries/test_finland.py (5)

298-306: Well-structured test for Åland's Autonomy Day in Finland.

The new test method effectively verifies:

  1. The holiday exists on June 9th from 1993-2049 when using subdivision "01"
  2. The holiday does not exist before 1993 with the same subdivision
  3. The holiday never appears without specifying the subdivision

This comprehensively tests the holiday's implementation in the Finland class.


388-388: Finnish localization test updated with Åland's Autonomy Day.

The Finnish localization test now includes "Ahvenanmaan itsehallintopäivä" for June 9, ensuring proper localization of the holiday name.


428-428: English localization test updated with Åland's Autonomy Day.

The English (US) localization test now properly includes "Åland's Autonomy Day" for June 9.


468-468: Ukrainian localization test updated with Åland's Autonomy Day.

The Ukrainian localization test now correctly includes "День автономії Аландських островів" for June 9.


508-508: Swedish localization test updated with Åland's Autonomy Day.

The Swedish (Finland) localization test now correctly includes "Ålands självstyrelsedag" for June 9.

tests/countries/test_aland_islands.py (8)

20-24: Test class setup looks good.

The test class properly inherits from both CommonCountryTests and TestCase, and the setUpClass method correctly initializes the test with the HolidaysAX class.


25-27: Appropriate alias testing.

The test correctly verifies that HolidaysAX, Aland, AX, and ALA are all valid aliases for the same holiday class.


28-30: Proper historic verification.

This test correctly verifies that no holidays exist for the year 1920, which is before the start year for Åland Islands holidays.


31-35: Comprehensive testing of Åland's Autonomy Day.

The test properly verifies:

  1. The holiday exists on June 9th for years 1993-2049
  2. The holiday does not exist for years 1921-1992

This correctly tests both the presence and absence of the holiday during relevant time periods.


36-73: Default language localization test is comprehensive.

The test verifies all holidays in 2022 with their Swedish names (the default language for Åland). The test includes regular Finland holidays and the special "Ålands självstyrelsedag" (Åland's Autonomy Day) on June 9.


75-113: English (US) localization test is comprehensive.

The test correctly verifies that all holiday names are properly translated into English, including "Åland's Autonomy Day" on June 9.


115-153: Finnish localization test is comprehensive.

The test correctly verifies that all holiday names are properly translated into Finnish, including "Ahvenanmaan itsehallintopäivä" (Åland's Autonomy Day) on June 9.


155-193: Ukrainian localization test is comprehensive.

The test correctly verifies that all holiday names are properly translated into Ukrainian, including "День автономії Аландських островів" (Åland's Autonomy Day) on June 9.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

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

15-15: 🧹 Nitpick (assertive)

Remove unused import.

The UNOFFICIAL constant is imported but not used in this test file.

-from holidays.constants import UNOFFICIAL
 from holidays.countries.aland_islands import HolidaysAX, Aland, AX, ALA
🧰 Tools
🪛 Ruff (0.8.2)

15-15: holidays.constants.UNOFFICIAL imported but unused

Remove unused import: holidays.constants.UNOFFICIAL

(F401)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c8b7274 and bee78d9.

📒 Files selected for processing (9)
  • AUTHORS.md (1 hunks)
  • README.md (2 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/holiday_base.py (1 hunks)
  • holidays/registry.py (1 hunks)
  • scripts/l10n/generate_po_files.py (1 hunks)
  • tests/common.py (1 hunks)
  • tests/countries/test_aland_islands.py (1 hunks)
  • tests/countries/test_finland.py (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
tests/common.py (1)
Learnt from: KJhellico
PR: vacanza/holidays#2398
File: tests/countries/test_guinea.py:237-239
Timestamp: 2025-04-02T18:38:35.164Z
Learning: In the vacanza/holidays project, the method assertLocalizedHolidays in country test files should be called with positional parameters rather than named parameters to maintain consistency with the rest of the codebase.
tests/countries/test_aland_islands.py (2)
Learnt from: KJhellico
PR: vacanza/holidays#2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions.
Learnt from: KJhellico
PR: vacanza/holidays#2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions to enhance code readability by clearly separating high-level components.
🧬 Code Graph Analysis (3)
holidays/countries/__init__.py (1)
holidays/countries/aland_islands.py (4)
  • Aland (51-52)
  • AX (55-56)
  • ALA (59-60)
  • HolidaysAX (17-48)
tests/countries/test_aland_islands.py (3)
tests/common.py (7)
  • TestCase (28-338)
  • CommonCountryTests (356-374)
  • assertAliases (121-130)
  • assertNoHolidays (292-294)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
  • assertLocalizedHolidays (327-338)
holidays/countries/aland_islands.py (4)
  • HolidaysAX (17-48)
  • Aland (51-52)
  • AX (55-56)
  • ALA (59-60)
tests/countries/test_finland.py (6)
  • setUpClass (22-24)
  • test_country_aliases (26-27)
  • test_alands_autonomy_day (298-305)
  • test_l10n_default (368-405)
  • test_l10n_en_us (407-445)
  • test_l10n_uk (447-485)
tests/countries/test_finland.py (3)
tests/countries/test_aland_islands.py (1)
  • test_alands_autonomy_day (31-34)
holidays/countries/finland.py (1)
  • Finland (21-196)
tests/common.py (2)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
🪛 Ruff (0.8.2)
tests/countries/test_aland_islands.py

15-15: holidays.constants.UNOFFICIAL imported but unused

Remove unused import: holidays.constants.UNOFFICIAL

(F401)

🔇 Additional comments (16)
AUTHORS.md (1)

21-21: Alphabetical ordering is correct

The new author "Ary Hauffe Neto" is placed between "Artem Tserekh" and "Bailey Thompson", maintaining ascending lexicographical order. Great addition!

tests/common.py (1)

337-338: LGTM - Simplified assertion behavior

This change appropriately simplifies the localized holiday assertion by directly passing the language parameter to the underlying method, matching production logic and improving maintainability.

holidays/countries/__init__.py (1)

16-16: LGTM - Added Åland Islands imports

The import for Åland Islands holiday classes is correctly added in alphabetical order, consistent with the rest of the file.

README.md (2)

151-156: Good structure and content for the Åland entry.

The new entry for Åland (AX) is well-structured and contains the necessary information - including proper reference to it being loadable as a Finland subdivision, supported languages with default language correctly highlighted, and the supported category.


524-524: Good update to Finland's regions.

Adding the Åland Islands (Ahvenanmaan maakunta, Landskapet Åland, Åland) as subdivision 01 in Finland's entry correctly connects the two entities.

tests/countries/test_finland.py (5)

298-305: Well-structured test for Åland's Autonomy Day.

The test correctly verifies that the Autonomy Day holiday:

  1. Exists from 1993 onwards for subdivision "01"
  2. Is not present before 1993
  3. Does not appear when no subdivision is specified

This comprehensive approach provides good test coverage for both presence and absence cases.


388-388: Correctly added Autonomy Day in localization tests.

The default language test now includes Åland's Autonomy Day with the correct Finnish name and date.


428-428: Proper English localization for Autonomy Day.

The English (US) localization test includes the correctly translated name for Åland's Autonomy Day.


468-468: Ukrainian localization for Autonomy Day looks good.

The Ukrainian localization test correctly includes the translated name for Åland's Autonomy Day.


508-508: Swedish localization for Autonomy Day properly included.

The Swedish (Finland) localization test includes the correct name for Åland's Autonomy Day.

holidays/holiday_base.py (1)

789-794: Improved language selection logic.

The refactored language selection provides clearer prioritization:

  1. First uses self.language if set and supported
  2. Then falls back to self.default_language if available
  3. Finally defaults to None if neither applies

This makes the translation initialization more robust and maintainable.

tests/countries/test_aland_islands.py (5)

31-34: Good test for Åland's Autonomy Day.

The test correctly verifies that Åland's Autonomy Day:

  1. Exists from 1993 onwards
  2. Is not present before 1993

This aligns with the implementation in the Finland class.


36-73: Comprehensive default language test.

The test thoroughly verifies all holidays in the default language (Swedish) for 2022, including regular Finland holidays and the Åland-specific Autonomy Day.


75-113: Good English localization test.

The test verifies that all holiday names are correctly translated to English (US), including Åland's Autonomy Day.


115-153: Finnish localization test looks good.

The test ensures all holiday names are correctly translated to Finnish. The Autonomy Day is correctly named as "Ahvenanmaan itsehallintopäivä".


155-193: Ukrainian localization test is comprehensive.

The test verifies correct Ukrainian translations for all holidays, including the Åland-specific Autonomy Day.

Comment on lines +22 to +23
def setUpClass(cls):
super().setUpClass(HolidaysAX)
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider extending the setup to include unofficial holidays.

The test for Finland includes setup for unofficial holidays, but this test doesn't. Consider extending the setup to cover unofficial holidays if they're relevant for Åland Islands.

 @classmethod
 def setUpClass(cls):
     super().setUpClass(HolidaysAX)
+    cls.unofficial_holidays = HolidaysAX(categories=UNOFFICIAL, years=range(1921, 2050))

If you do this, you'll need to keep the UNOFFICIAL import.

📝 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
def setUpClass(cls):
super().setUpClass(HolidaysAX)
@classmethod
def setUpClass(cls):
super().setUpClass(HolidaysAX)
cls.unofficial_holidays = HolidaysAX(categories=UNOFFICIAL, years=range(1921, 2050))

@github-actions github-actions bot added the ci label Apr 24, 2025
@sonarqubecloud
Copy link

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: 42

🔭 Outside diff range comments (14)
tests/test_docs.py (1)

28-49: ⚠️ Potential issue

Resolve merge conflict for TestAuthors class.

There's an unresolved merge conflict around the entire TestAuthors class definition. The static analysis tools are reporting syntax errors because of these merge markers.

Since you've added a new author to AUTHORS.md, you should keep the TestAuthors class. Apply this diff to resolve the conflict:

-<<<<<<< HEAD
class TestAuthors(TestCase):
    @classmethod
    def setUpClass(cls):
        cls.content = Path("AUTHORS.md").read_text(encoding="UTF-8").strip().split("\n")
        super().setUpClass()

    def test_header(self):
        self.assertEqual(self.content[0], "# Holidays Authors")

    def test_authors_list(self):
        authors = self.content[1:]
        self.assertEqual(
            authors,
            sorted(authors),
            "Contributors list should be sorted alphabetically.\n"
            + "\n".join((f"{c} != {s}" for c, s in zip(authors, sorted(authors)) if c != s)),
        )

-=======
->>>>>>> 7ee519e2 (WIP: recuperando alterações locais antes do merge)
🧰 Tools
🪛 Ruff (0.8.2)

28-28: SyntaxError: Expected a statement


28-28: SyntaxError: Expected a statement


28-28: SyntaxError: Expected a statement


28-28: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Simple statements must be separated by newlines or semicolons


49-49: SyntaxError: Expected ',', found ':'


49-49: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected ',', found name

snapshots/countries/VN_COMMON.json (1)

120-140: ⚠️ Potential issue

Invalid JSON – merge-conflict artefacts present

The snapshot now contains Git conflict markers in multiple places (example around 1965, 1968, 2007 blocks). Any consumer that attempts to load this snapshot (tests, lint checks) will fail.

Action:

  1. Decide which side of each conflict is the canonical timeline.
  2. Delete all <<<<<<<, =======, >>>>>>> banners.
  3. Ensure the file still contains valid, comma-separated JSON (run jq . snapshots/countries/VN_COMMON.json).

Until fixed, automated snapshot comparisons will crash.

Also applies to: 300-320, 510-560, 830-850, 940-970

tests/countries/test_singapore.py (1)

204-217: ⚠️ Potential issue

Resolve merge conflict in test_special_holidays method.

There's an unresolved merge conflict in the test_special_holidays method regarding which dates to include. Based on the AI summary, the method should test multiple special holiday dates.

-<<<<<<< HEAD
        self.assertHoliday(
            "2001-11-03",
            "2006-05-06",
            "2011-05-07",
            "2015-08-07",
            "2015-09-11",
            "2020-07-10",
            "2023-09-01",
            "2025-05-03",
        )
-=======
-        self.assertHoliday("2015-08-07")
->>>>>>> 7ee519e2 (WIP: recuperando alterações locais antes do merge)
+        self.assertHoliday(
+            "2001-11-03",
+            "2006-05-06",
+            "2011-05-07",
+            "2015-08-07",
+            "2015-09-11",
+            "2020-07-10",
+            "2023-09-01",
+            "2025-05-03",
+        )
🧰 Tools
🪛 Ruff (0.8.2)

204-204: SyntaxError: Expected a statement


204-204: SyntaxError: Expected a statement


204-204: SyntaxError: Expected a statement


204-204: SyntaxError: Expected a statement


205-205: SyntaxError: Unexpected indentation


215-215: SyntaxError: Expected a statement


215-215: SyntaxError: Expected a statement


215-215: SyntaxError: Expected a statement


215-215: SyntaxError: Expected a statement


215-216: SyntaxError: Expected a statement


216-216: SyntaxError: Unexpected indentation


217-217: SyntaxError: Expected a statement


217-217: SyntaxError: Expected a statement


217-217: SyntaxError: Expected a statement


217-217: SyntaxError: Expected a statement


217-217: SyntaxError: Simple statements must be separated by newlines or semicolons


217-217: SyntaxError: Expected ',', found ':'


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name

scripts/calendar/asian_generator.py (1)

268-293: ⚠️ Potential issue

Resolve merge conflict in G_LUNAR_MONTH_DAYS end and date range definition

There's a merge conflict affecting the end of the array and the date range definitions.

Based on the changes elsewhere, the corrected version should include the updated date range (2099 instead of 2100) and corresponding lunar/solar dates:

-<<<<<<< HEAD
-        0x22936,
-        0xF0956,  # 2100
-    )
-    # Define range of years covered
-    self.START_YEAR = 1901
-    self.END_YEAR = 2100
-    # The Gregorian date for the 1st day of the 1st month of 1900 year is 1901/2/19
-    self.LUNAR_START_DATE = ((1901, 1, 1),)
-    self.SOLAR_START_DATE = date(1901, 2, 19)
-    # The Gregorian date for the 29th day of 12th month of 2100 year is 2101/1/28
-    self.LUNAR_END_DATE = (2100, 12, 29)
-    self.SOLAR_END_DATE = date(2101, 1, 28)
-=======
-        0x22936,  # 2100
-    )
-    # Define range of years covered
-    self.START_YEAR = 1901
-    self.END_YEAR = 2099
-    # The 1st day of the 1st month of the Gregorian calendar is 1901/2/19
-    self.LUNAR_START_DATE = ((1901, 1, 1),)
-    self.SOLAR_START_DATE = date(1901, 2, 19)
-    # The Gregorian date for December 30, 2099 is 2100/2/8
-    self.LUNAR_END_DATE = (2099, 12, 30)
-    self.SOLAR_END_DATE = date(2100, 2, 18)
->>>>>>> 7ee519e2 (WIP: recuperando alterações locais antes do merge)
+        0x22936,  # 2100
+    )
+    # Define range of years covered
+    self.START_YEAR = 1901
+    self.END_YEAR = 2099
+    # The 1st day of the 1st month of the Gregorian calendar is 1901/2/19
+    self.LUNAR_START_DATE = ((1901, 1, 1),)
+    self.SOLAR_START_DATE = date(1901, 2, 19)
+    # The Gregorian date for December 30, 2099 is 2100/2/8
+    self.LUNAR_END_DATE = (2099, 12, 30)
+    self.SOLAR_END_DATE = date(2100, 2, 18)
🧰 Tools
🪛 Ruff (0.8.2)

268-268: SyntaxError: Expected a statement


268-268: SyntaxError: Expected a statement


268-268: SyntaxError: Expected a statement


268-268: SyntaxError: Expected a statement


269-269: SyntaxError: Unexpected indentation


271-271: SyntaxError: unindent does not match any outer indentation level


271-271: SyntaxError: Expected a statement


271-272: SyntaxError: Expected a statement


273-273: SyntaxError: Unexpected indentation


281-281: SyntaxError: Expected a statement


281-281: SyntaxError: Expected a statement


281-281: SyntaxError: Expected a statement


281-281: SyntaxError: Expected a statement


281-282: SyntaxError: Expected a statement


282-282: SyntaxError: Unexpected indentation


283-283: SyntaxError: unindent does not match any outer indentation level


283-283: SyntaxError: Expected a statement


283-284: SyntaxError: Expected a statement


285-285: SyntaxError: Unexpected indentation


293-293: SyntaxError: Expected a statement


293-293: SyntaxError: Expected a statement


293-293: SyntaxError: Expected a statement


293-293: SyntaxError: Expected a statement


293-293: SyntaxError: Simple statements must be separated by newlines or semicolons


293-293: SyntaxError: Expected ',', found ':'


293-293: SyntaxError: Expected ',', found name


293-293: SyntaxError: Expected ',', found name


293-293: SyntaxError: Expected ',', found name


293-293: SyntaxError: Expected ',', found name


293-293: SyntaxError: Expected ',', found name

holidays/locale/en_US/LC_MESSAGES/ET.po (2)

48-90: ⚠️ Potential issue

Resolve merge conflict in Christmas Day msgid and other holiday entries

There's a merge conflict affecting the Christmas Day and other holiday entries.

The PR appears to be replacing longer Amharic strings with shorter ones. Since this is related to standardizing msgids, the newer (shorter) versions should be selected:

-<<<<<<< HEAD
-msgid "የገና ወይም የልደት በዓል"
-msgstr "Christmas Day"
-
-#. Epiphany.
-msgid "የጥምቀት በዓል"
-msgstr "Epiphany"
-
-#. Adwa Victory Day.
-msgid "የአድዋ ድል በዓል"
-msgstr "Adwa Victory Day"
-
-#. Good Friday.
-msgid "የስቅለት በዓል"
-msgstr "Good Friday"
-
-#. Easter Sunday.
-msgid "የትንሳኤ(ፋሲካ) በዓል"
-msgstr "Easter Sunday"
-
-#. International Workers' Day.
-msgid "የዓለም የሠራተኞች (የላብአደሮች) ቀን"
-msgstr "International Workers' Day"
-
-#. Ethiopian Patriots' Victory Day.
-msgid "የአርበኞች (የድል) ቀን በዓል"
-msgstr "Ethiopian Patriots' Victory Day"
-
-#. Downfall of the Dergue Regime Day.
-msgid "ደርግ የወደቀበት ቀን"
-msgstr "Downfall of the Dergue Regime Day"
-
-#. Ethiopian New Year.
-msgid "የዘመን መለወጫ (እንቁጣጣሽ) በዓል"
-msgstr "Ethiopian New Year"
-
-#. Finding of True Cross.
-msgid "የመስቀል በዓል"
-msgstr "Finding of True Cross"
-
-#. Popular Revolution Commemoration Day.
-msgid "የአብዮት ቀን"
-msgstr "Popular Revolution Commemoration Day"
-=======
-msgid "ገና"
-msgstr "Christmas Day"
-
-#. Epiphany.
-msgid "ጥምቀት"
-msgstr "Epiphany Day"
-
-#. Adwa Victory Day.
-msgid "አድዋ"
-msgstr "Adwa Victory Day"
-
-#. Good Friday.
-msgid "ስቅለት"
-msgstr "Good Friday"
-
-#. Easter Sunday.
-msgid "ፋሲካ"
-msgstr "Easter Sunday"
-
-#. Workers' Day.
-msgid "የሰራተኞች ቀን"
-msgstr "Workers' Day"
-
-#. Patriots' Day.
-msgid "የአርበኞች ቀን"
-msgstr "Patriots' Day"
-
-#. Downfall of Dergue Regime Day.
-msgid "ደርግ የወደቀበት ቀን"
-msgstr "Downfall of Dergue Regime Day"
-
-#. Ethiopian New Year.
-msgid "እንቁጣጣሽ"
-msgstr "Ethiopian New Year"
-
-#. Finding of True Cross.
-msgid "መስቀል"
-msgstr "Finding of True Cross"
-
-#. Revolution Day.
-msgid "የአብዮት ቀን"
-msgstr "Revolution Day"
->>>>>>> 7ee519e2 (WIP: recuperando alterações locais antes do merge)
+msgid "ገና"
+msgstr "Christmas Day"
+
+#. Epiphany.
+msgid "ጥምቀት"
+msgstr "Epiphany Day"
+
+#. Adwa Victory Day.
+msgid "አድዋ"
+msgstr "Adwa Victory Day"
+
+#. Good Friday.
+msgid "ስቅለት"
+msgstr "Good Friday"
+
+#. Easter Sunday.
+msgid "ፋሲካ"
+msgstr "Easter Sunday"
+
+#. Workers' Day.
+msgid "የሰራተኞች ቀን"
+msgstr "Workers' Day"
+
+#. Patriots' Day.
+msgid "የአርበኞች ቀን"
+msgstr "Patriots' Day"
+
+#. Downfall of Dergue Regime Day.
+msgid "ደርግ የወደቀበት ቀን"
+msgstr "Downfall of Dergue Regime Day"
+
+#. Ethiopian New Year.
+msgid "እንቁጣጣሽ"
+msgstr "Ethiopian New Year"
+
+#. Finding of True Cross.
+msgid "መስቀል"
+msgstr "Finding of True Cross"
+
+#. Revolution Day.
+msgid "የአብዮት ቀን"
+msgstr "Revolution Day"

Note the translation change from "Popular Revolution Commemoration Day" to "Revolution Day" - this appears to be a deliberate shortening of the holiday name.


141-171: ⚠️ Potential issue

Resolve merge conflict in Eid al-Fitr and other holiday entries

There's a merge conflict affecting the Eid al-Fitr and other holiday msgids.

Similar to the previous conflict, selecting the shorter msgids appears to be the intended approach:

-<<<<<<< HEAD
-msgid "የኢድ አልፈጥር"
-msgstr "Eid al-Fitr"
-
-#. Eid al-Adha.
-msgid "የኢድ አልአድሃ (አረፋ)"
-msgstr "Eid al-Adha"
-
-#. Prophet's Birthday.
-msgid "የመውሊድ በዓል"
-msgstr "Prophet's Birthday"
-
-#. Ethiopian Martyrs' Day.
-msgid "የሰማዕታት ቀን"
-msgstr "Ethiopian Martyrs' Day"
-
-#. Nations, Nationalities and Peoples Day.
-msgid "የብሔር ብሔረሰቦች ቀን"
-msgstr "Nations, Nationalities and Peoples Day"
-=======
-msgid "ኢድ አልፈጥር"
-msgstr "Eid al-Fitr"
-
-#. Eid al-Adha.
-msgid "አረፋ"
-msgstr "Eid al-Adha"
-
-#. Prophet's Birthday.
-msgid "መውሊድ"
-msgstr "Prophet's Birthday"
->>>>>>> 7ee519e2 (WIP: recuperando alterações locais antes do merge)
+msgid "ኢድ አልፈጥር"
+msgstr "Eid al-Fitr"
+
+#. Eid al-Adha.
+msgid "አረፋ"
+msgstr "Eid al-Adha"
+
+#. Prophet's Birthday.
+msgid "መውሊድ"
+msgstr "Prophet's Birthday"
+
+#. Ethiopian Martyrs' Day.
+msgid "የሰማዕታት ቀን"
+msgstr "Ethiopian Martyrs' Day"
+
+#. Nations, Nationalities and Peoples Day.
+msgid "የብሔር ብሔረሰቦች ቀን"
+msgstr "Nations, Nationalities and Peoples Day"

Note that the last two entries (Ethiopian Martyrs' Day and Nations, Nationalities and Peoples Day) are only present in the HEAD version and should be retained.

holidays/locale/ar/LC_MESSAGES/ET.po (2)

48-91: ⚠️ Potential issue

Resolve merge conflict in holiday translations - Part 1.

This section contains conflicts between longer descriptive holiday names (HEAD) and shorter standardized names (incoming change). For consistency with other language files, adopt the shorter standardized message IDs with their corresponding Arabic translations.

Note that the incoming branch uses simpler, more maintainable holiday names (e.g., "ገና" instead of "የገና ወይም የልደት በዓል") that match the standardization efforts in the codebase.


141-171: ⚠️ Potential issue

Resolve merge conflict in holiday translations - Part 2.

Similar to the previous conflict, adopt the shorter, standardized holiday names from the incoming change for consistency with other language files.

The change from lengthy message IDs to brief ones (e.g., "የኢድ አልፈጥር" to "ኢድ አልፈጥር") follows the project's apparent standardization efforts, while maintaining the same Arabic translations.

holidays/locale/am/LC_MESSAGES/ET.po (2)

46-128: ⚠️ Potential issue

Resolve merge conflict in holiday translations - Main section.

Similar to the Arabic localization file, adopt the shorter standardized holiday names from the incoming change for consistency with the rest of the codebase.

The pattern here is clear - the incoming changes use shorter, more concise message IDs (e.g., "ገና" instead of "የገና ወይም የልደት በዓል") that match the standardization in the Ethiopian holiday implementation.


135-165: ⚠️ Potential issue

Resolve merge conflict in holiday translations - Additional holidays.

Complete the merge conflict resolution by adopting the shorter holiday names from the incoming changes for Eid, Prophet's Birthday, and other holiday entries.

Note that these changes are consistent with similar standardization in the Arabic translations and likely in the core holiday logic as well.

snapshots/countries/ET_COMMON.json (2)

2-13: ⚠️ Potential issue

Resolve merge conflict in Ethiopian holiday data - Start section.

The file contains extensive merge conflicts in the Ethiopian holiday data. The incoming change (7ee519e2) contains a much more comprehensive dataset starting from 1950, while the HEAD version has fewer entries.

During resolution, adopt the expanded dataset from the incoming change which provides holidays from 1950-2050 rather than the limited set in HEAD.


1391-1442: 💡 Verification agent

🧩 Analysis chain

Verify that no holidays are lost during merge.

While merging, carefully verify that important holidays from HEAD aren't lost in the incoming change. For example, "Nations, Nationalities and Peoples Day" appears in HEAD but not in the incoming changes.

Check with product owners or documentation whether this holiday should be maintained in the final merged version:


🏁 Script executed:

#!/bin/bash
# Check if "Nations, Nationalities and Peoples Day" appears in other files
grep -r "Nations, Nationalities and Peoples Day" --include="*.py" .

Length of output: 261


Let’s confirm that the 2022 entry is present in the snapshot JSON:


🏁 Script executed:

#!/bin/bash
# Check for the 2022 “Nations, Nationalities and Peoples Day” entry
grep -R '"2022-12-09":' -n snapshots/countries/ET_COMMON.json

Length of output: 128


Retain “Nations, Nationalities and Peoples Day” in the ET_COMMON snapshot

The incoming merge dropped the Dec 9 entries for this holiday in 2017 and 2018 (and possibly 2019). Since it’s still defined in holidays/countries/ethiopia.py and covered by your 2022 test, please re-add it for all years in snapshots/countries/ET_COMMON.json:

• 2017-12-09: "Nations, Nationalities and Peoples Day"
• 2018-12-09: "Nations, Nationalities and Peoples Day"
• (and 2019-12-09 if your snapshot spans that year)

Fixing this will keep tests and documentation aligned.

holidays/calendars/chinese.py (1)

1366-1400: 🛠️ Refactor suggestion

Mixed old/new API — callers will mis-match

One branch defines:

def _get_holiday(self, holiday, year)

but the other keeps the earlier variant that accepts calendar=None, and several public helpers (lunar_new_year_date, etc.) still forward that parameter.

Decide on one API (prefer the simpler two-parameter version, per PR description) and drop the extra argument everywhere:

-def lunar_new_year_date(self, year: int, calendar=None):
-    return self._get_holiday(LUNAR_NEW_YEAR, year, calendar)
+def lunar_new_year_date(self, year: int) -> tuple[Optional[date], bool]:
+    return self._get_holiday(LUNAR_NEW_YEAR, year)

Repeat for buddha_birthday_date, hung_kings_date, mid_autumn_date.

🧰 Tools
🪛 Ruff (0.8.2)

1374-1374: SyntaxError: Expected a statement


1374-1374: SyntaxError: Expected a statement


1374-1374: SyntaxError: Expected a statement


1374-1374: SyntaxError: Expected a statement


1374-1374: SyntaxError: Simple statements must be separated by newlines or semicolons


1374-1374: SyntaxError: Expected ',', found ':'


1374-1374: SyntaxError: Expected ',', found name


1374-1374: SyntaxError: Expected ',', found name


1374-1374: SyntaxError: Expected ',', found name


1374-1374: SyntaxError: Expected ',', found name


1374-1374: SyntaxError: Expected ',', found name


1376-1376: SyntaxError: Unexpected indentation


1382-1382: SyntaxError: Expected a statement


1382-1382: SyntaxError: Expected a statement


1382-1382: SyntaxError: Expected a statement


1382-1382: SyntaxError: Expected a statement


1383-1383: SyntaxError: Unexpected indentation


1391-1391: SyntaxError: Expected a statement


1391-1391: SyntaxError: Expected a statement


1391-1391: SyntaxError: Expected a statement


1391-1391: SyntaxError: Expected a statement


1391-1392: SyntaxError: Expected a statement


1392-1392: SyntaxError: Unexpected indentation


1400-1400: SyntaxError: Expected a statement


1400-1400: SyntaxError: Expected a statement


1400-1400: SyntaxError: Expected a statement


1400-1400: SyntaxError: Expected a statement


1400-1400: SyntaxError: Simple statements must be separated by newlines or semicolons


1400-1400: SyntaxError: Expected ',', found ':'


1400-1400: SyntaxError: Expected ',', found name


1400-1400: SyntaxError: Expected ',', found name


1400-1400: SyntaxError: Expected ',', found name


1400-1400: SyntaxError: Expected ',', found name


1400-1400: SyntaxError: Expected ',', found name

tests/countries/test_ethiopia.py (1)

269-350: 🧹 Nitpick (assertive)

Orphaned WORKDAY-category tests

If you decide to drop the WORKDAY category import, also delete the Martyrs’ Day & Nations-and-Nationalities tests that rely on self.workday_holidays. Otherwise keep the richer setup. Leaving half-applied refactors will silently skip important assertions.

🧰 Tools
🪛 Ruff (0.8.2)

269-269: SyntaxError: Expected ',', found '<<'


269-269: SyntaxError: Expected ',', found '<<'


269-269: SyntaxError: Expected ',', found '<<'


269-269: SyntaxError: Expected ',', found '<'


270-270: SyntaxError: Expected ',', found string


274-274: SyntaxError: unindent does not match any outer indentation level


281-281: SyntaxError: unindent does not match any outer indentation level


289-289: SyntaxError: unindent does not match any outer indentation level


308-308: SyntaxError: unindent does not match any outer indentation level


328-328: SyntaxError: unindent does not match any outer indentation level


349-349: SyntaxError: Expected ',', found '=='


349-349: SyntaxError: Expected ',', found '=='


349-349: SyntaxError: Expected ',', found '=='


349-349: SyntaxError: Expected ',', found '='

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bee78d9 and 2eb19bf.

📒 Files selected for processing (30)
  • .github/workflows/ci-cd.yml (1 hunks)
  • .pre-commit-config.yaml (0 hunks)
  • AUTHORS.md (2 hunks)
  • CHANGES.md (0 hunks)
  • README.md (3 hunks)
  • SECURITY.md (1 hunks)
  • holidays/calendars/buddhist.py (4 hunks)
  • holidays/calendars/chinese.py (11 hunks)
  • holidays/calendars/hindu.py (3 hunks)
  • holidays/countries/ethiopia.py (8 hunks)
  • holidays/countries/singapore.py (2 hunks)
  • holidays/countries/south_korea.py (3 hunks)
  • holidays/countries/vietnam.py (2 hunks)
  • holidays/groups/chinese.py (2 hunks)
  • holidays/locale/am/LC_MESSAGES/ET.po (5 hunks)
  • holidays/locale/ar/LC_MESSAGES/ET.po (3 hunks)
  • holidays/locale/en_US/LC_MESSAGES/ET.po (3 hunks)
  • holidays/version.py (1 hunks)
  • requirements/build.txt (1 hunks)
  • requirements/dev.txt (1 hunks)
  • scripts/calendar/asian_generator.py (9 hunks)
  • snapshots/countries/ET_COMMON.json (55 hunks)
  • snapshots/countries/SG_COMMON.json (1 hunks)
  • snapshots/countries/VN_COMMON.json (8 hunks)
  • tests/countries/test_aland_islands.py (1 hunks)
  • tests/countries/test_ethiopia.py (9 hunks)
  • tests/countries/test_finland.py (5 hunks)
  • tests/countries/test_singapore.py (3 hunks)
  • tests/countries/test_vietnam.py (1 hunks)
  • tests/test_docs.py (2 hunks)
💤 Files with no reviewable changes (2)
  • .pre-commit-config.yaml
  • CHANGES.md
🧰 Additional context used
🧠 Learnings (3)
holidays/countries/ethiopia.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2490
File: holidays/countries/ethiopia.py:45-45
Timestamp: 2025-04-23T09:59:19.848Z
Learning: For the Ethiopia holidays class, it's appropriate to add a return type hint only to the `_is_leap_year` method to match the base class implementation in `holidays/holiday_base.py`, while keeping other methods without type hints to maintain consistency with other country implementations.
tests/countries/test_ethiopia.py (2)
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.
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.
tests/countries/test_aland_islands.py (4)
Learnt from: KJhellico
PR: vacanza/holidays#2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions.
Learnt from: KJhellico
PR: vacanza/holidays#2449
File: tests/countries/test_aland_islands.py:13-17
Timestamp: 2025-04-10T09:35:45.752Z
Learning: According to PEP 8 style guidelines for Python, there should be two blank lines before top-level class definitions to enhance code readability by clearly separating high-level components.
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#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.
🧬 Code Graph Analysis (7)
tests/countries/test_singapore.py (1)
tests/common.py (1)
  • assertHoliday (150-152)
holidays/countries/vietnam.py (1)
holidays/groups/chinese.py (1)
  • ChineseCalendarHolidays (25-28)
holidays/groups/chinese.py (1)
holidays/calendars/chinese.py (1)
  • _ChineseLunisolar (34-236)
holidays/countries/south_korea.py (2)
holidays/calendars/chinese.py (1)
  • _CustomChineseHolidays (1403-1404)
holidays/groups/chinese.py (1)
  • ChineseCalendarHolidays (25-28)
holidays/countries/ethiopia.py (4)
holidays/groups/christian.py (3)
  • _add_christmas_day (208-216)
  • _add_good_friday (308-317)
  • _add_easter_sunday (270-279)
holidays/holiday_base.py (1)
  • _add_holiday (824-836)
holidays/groups/international.py (1)
  • _add_labor_day (99-108)
holidays/groups/islamic.py (3)
  • _add_eid_al_fitr_day (152-163)
  • _add_eid_al_adha_day (109-120)
  • _add_mawlid_day (329-339)
tests/countries/test_finland.py (3)
tests/countries/test_aland_islands.py (1)
  • test_alands_autonomy_day (35-37)
holidays/countries/finland.py (1)
  • Finland (21-196)
tests/common.py (2)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
tests/countries/test_ethiopia.py (2)
holidays/countries/ethiopia.py (3)
  • Ethiopia (29-48)
  • ET (195-196)
  • ETH (199-200)
tests/common.py (7)
  • CommonCountryTests (356-374)
  • TestCase (28-338)
  • assertAliases (121-130)
  • assertNoHolidays (292-294)
  • assertHolidayName (195-199)
  • assertNoHolidayName (273-275)
  • assertLocalizedHolidays (327-338)
🪛 Ruff (0.8.2)
tests/countries/test_vietnam.py

72-72: SyntaxError: Expected ',', found '<<'


72-72: SyntaxError: Expected ',', found '<<'


72-72: SyntaxError: Expected ',', found '<<'


72-72: SyntaxError: Expected ',', found '<'


73-73: SyntaxError: Expected ',', found string


74-74: SyntaxError: Expected ',', found '=='


74-74: SyntaxError: Expected ',', found '=='


74-74: SyntaxError: Expected ',', found '=='


74-74: SyntaxError: Expected ',', found '='


76-76: SyntaxError: Expected ',', found '>>'


76-76: SyntaxError: Expected ',', found '>>'


76-76: SyntaxError: Expected ',', found '>>'


76-76: SyntaxError: Expected ',', found '>'


76-76: SyntaxError: Expected ',', found name


76-76: SyntaxError: Expected ',', found ':'


76-76: SyntaxError: Expected ',', found name


76-76: SyntaxError: Expected ',', found name


76-76: SyntaxError: Expected ',', found name


76-76: SyntaxError: Expected ',', found name


76-76: SyntaxError: Expected ',', found name

holidays/countries/singapore.py

333-333: SyntaxError: Expected ',', found '<<'


333-333: SyntaxError: Expected ',', found '<<'


333-333: SyntaxError: Expected ',', found '<<'


333-333: SyntaxError: Expected ',', found '<'


334-334: SyntaxError: Expected ':', found int


334-334: SyntaxError: Expected ',', found ':'


334-334: SyntaxError: Expected ':', found ','


335-335: SyntaxError: Expected ',', found '=='


335-335: SyntaxError: Expected ',', found '=='


335-335: SyntaxError: Expected ',', found '=='


335-335: SyntaxError: Expected ',', found '='


336-336: SyntaxError: Expected ',', found '>>'


336-336: SyntaxError: Expected ',', found '>>'


336-336: SyntaxError: Expected ',', found '>>'


336-336: SyntaxError: Expected ',', found '>'


336-336: SyntaxError: Expected ':', found name


336-336: SyntaxError: Expected ',', found ':'


336-336: SyntaxError: Expected ',', found name


336-336: SyntaxError: Expected ',', found name


336-336: SyntaxError: Expected ',', found name


336-336: SyntaxError: Expected ',', found name


336-336: SyntaxError: Expected ',', found name

holidays/version.py

13-13: SyntaxError: Expected a statement


13-13: SyntaxError: Expected a statement


13-13: SyntaxError: Expected a statement


13-13: SyntaxError: Expected a statement


15-15: SyntaxError: Expected a statement


15-15: SyntaxError: Expected a statement


15-15: SyntaxError: Expected a statement


15-15: SyntaxError: Expected a statement


15-16: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Simple statements must be separated by newlines or semicolons


17-17: SyntaxError: Expected ',', found ':'


17-17: SyntaxError: Expected ',', found name


17-17: SyntaxError: Expected ',', found name


17-17: SyntaxError: Expected ',', found name


17-17: SyntaxError: Expected ',', found name


17-17: SyntaxError: Expected ',', found name

tests/countries/test_singapore.py

189-189: SyntaxError: Expected ',', found '<<'


189-189: SyntaxError: Expected ',', found '<<'


189-189: SyntaxError: Expected ',', found '<<'


189-189: SyntaxError: Expected ',', found '<'


191-191: SyntaxError: Expected ',', found '=='


191-191: SyntaxError: Expected ',', found '=='


191-191: SyntaxError: Expected ',', found '=='


191-191: SyntaxError: Expected ',', found '='


192-192: SyntaxError: Expected ',', found '>>'


192-192: SyntaxError: Expected ',', found '>>'


192-192: SyntaxError: Expected ',', found '>>'


192-192: SyntaxError: Expected ',', found '>'


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found ':'


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found name


203-204: SyntaxError: Expected an indented block after function definition


204-204: SyntaxError: Expected a statement


204-204: SyntaxError: Expected a statement


204-204: SyntaxError: Expected a statement


204-204: SyntaxError: Expected a statement


215-215: SyntaxError: Expected a statement


215-215: SyntaxError: Expected a statement


215-215: SyntaxError: Expected a statement


215-215: SyntaxError: Expected a statement


215-216: SyntaxError: Expected a statement


216-216: SyntaxError: Unexpected indentation


217-217: SyntaxError: Expected a statement


217-217: SyntaxError: Expected a statement


217-217: SyntaxError: Expected a statement


217-217: SyntaxError: Expected a statement


217-217: SyntaxError: Simple statements must be separated by newlines or semicolons


217-217: SyntaxError: Expected ',', found ':'


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name

holidays/countries/vietnam.py

16-16: SyntaxError: Expected a statement


16-16: SyntaxError: Expected a statement


16-16: SyntaxError: Expected a statement


16-16: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Simple statements must be separated by newlines or semicolons


19-19: SyntaxError: Expected ',', found ':'


19-19: SyntaxError: Expected ',', found name


19-19: SyntaxError: Expected ',', found name


19-19: SyntaxError: Expected ',', found name


19-19: SyntaxError: Expected ',', found name


19-19: SyntaxError: Expected ',', found name


66-66: SyntaxError: Expected a statement


66-66: SyntaxError: Expected a statement


66-66: SyntaxError: Expected a statement


66-66: SyntaxError: Expected a statement


67-67: SyntaxError: Unexpected indentation


68-68: SyntaxError: Expected a statement


68-68: SyntaxError: Expected a statement


68-68: SyntaxError: Expected a statement


68-68: SyntaxError: Expected a statement


68-69: SyntaxError: Expected a statement


69-69: SyntaxError: Unexpected indentation


70-70: SyntaxError: Expected a statement


70-70: SyntaxError: Expected a statement


70-70: SyntaxError: Expected a statement


70-70: SyntaxError: Expected a statement


70-70: SyntaxError: Simple statements must be separated by newlines or semicolons


70-70: SyntaxError: Expected ',', found ':'


70-70: SyntaxError: Expected ',', found name


70-70: SyntaxError: Expected ',', found name


70-70: SyntaxError: Expected ',', found name


70-70: SyntaxError: Expected ',', found name


70-70: SyntaxError: Expected ',', found name

tests/test_docs.py

28-28: SyntaxError: Expected a statement


28-28: SyntaxError: Expected a statement


28-28: SyntaxError: Expected a statement


28-28: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Expected a statement


48-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Simple statements must be separated by newlines or semicolons


49-49: SyntaxError: Expected ',', found ':'


49-49: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected ',', found name

holidays/groups/chinese.py

16-16: SyntaxError: Expected a statement


16-16: SyntaxError: Expected a statement


16-16: SyntaxError: Expected a statement


16-16: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-19: SyntaxError: Expected a statement


20-20: SyntaxError: Expected a statement


20-20: SyntaxError: Expected a statement


20-20: SyntaxError: Expected a statement


20-20: SyntaxError: Expected a statement


20-20: SyntaxError: Simple statements must be separated by newlines or semicolons


20-20: SyntaxError: Expected ',', found ':'


20-20: SyntaxError: Expected ',', found name


20-20: SyntaxError: Expected ',', found name


20-20: SyntaxError: Expected ',', found name


20-20: SyntaxError: Expected ',', found name


20-20: SyntaxError: Expected ',', found name


30-30: SyntaxError: Expected a statement


30-30: SyntaxError: Expected a statement


30-30: SyntaxError: Expected a statement


30-30: SyntaxError: Expected a statement


31-31: SyntaxError: Unexpected indentation


35-35: SyntaxError: Expected a statement


35-35: SyntaxError: Expected a statement


35-35: SyntaxError: Expected a statement


35-35: SyntaxError: Expected a statement


35-36: SyntaxError: Expected a statement


36-36: SyntaxError: Unexpected indentation


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Simple statements must be separated by newlines or semicolons


38-38: SyntaxError: Expected ',', found ':'


38-38: SyntaxError: Expected ',', found name


38-38: SyntaxError: Expected ',', found name


38-38: SyntaxError: Expected ',', found name


38-38: SyntaxError: Expected ',', found name


38-38: SyntaxError: Expected ',', found name

holidays/countries/south_korea.py

17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-20: SyntaxError: Expected a statement


21-21: SyntaxError: Expected a statement


21-21: SyntaxError: Expected a statement


21-21: SyntaxError: Expected a statement


21-21: SyntaxError: Expected a statement


21-21: SyntaxError: Simple statements must be separated by newlines or semicolons


21-21: SyntaxError: Expected ',', found ':'


21-21: SyntaxError: Expected ',', found name


21-21: SyntaxError: Expected ',', found name


21-21: SyntaxError: Expected ',', found name


21-21: SyntaxError: Expected ',', found name


21-21: SyntaxError: Expected ',', found name


94-94: SyntaxError: Expected a statement


94-94: SyntaxError: Expected a statement


94-94: SyntaxError: Expected a statement


94-94: SyntaxError: Expected a statement


95-95: SyntaxError: Unexpected indentation


96-96: SyntaxError: Expected a statement


96-96: SyntaxError: Expected a statement


96-96: SyntaxError: Expected a statement


96-96: SyntaxError: Expected a statement


96-97: SyntaxError: Expected a statement


97-97: SyntaxError: Unexpected indentation


98-98: SyntaxError: Expected a statement


98-98: SyntaxError: Expected a statement


98-98: SyntaxError: Expected a statement


98-98: SyntaxError: Expected a statement


98-98: SyntaxError: Simple statements must be separated by newlines or semicolons


98-98: SyntaxError: Expected ',', found ':'


98-98: SyntaxError: Expected ',', found name


98-98: SyntaxError: Expected ',', found name


98-98: SyntaxError: Expected ',', found name


98-98: SyntaxError: Expected ',', found name


98-98: SyntaxError: Expected ',', found name


300-300: SyntaxError: Expected a statement


300-300: SyntaxError: Expected a statement


300-300: SyntaxError: Expected a statement


300-300: SyntaxError: Expected a statement


301-301: SyntaxError: Expected a statement


301-301: SyntaxError: Expected a statement


301-301: SyntaxError: Expected a statement


301-301: SyntaxError: Expected a statement


301-302: SyntaxError: Expected a statement


330-330: SyntaxError: Expected a statement


330-330: SyntaxError: Expected a statement


330-330: SyntaxError: Expected a statement


330-330: SyntaxError: Expected a statement


330-330: SyntaxError: Simple statements must be separated by newlines or semicolons


330-330: SyntaxError: Expected ',', found ':'


330-330: SyntaxError: Expected ',', found name


330-330: SyntaxError: Expected ',', found name


330-330: SyntaxError: Expected ',', found name


330-330: SyntaxError: Expected ',', found name


330-330: SyntaxError: Expected ',', found name

holidays/calendars/hindu.py

138-138: SyntaxError: Expected ',', found '<<'


138-138: SyntaxError: Expected ',', found '<<'


138-138: SyntaxError: Expected ',', found '<<'


138-138: SyntaxError: Expected ',', found '<'


139-139: SyntaxError: Expected ':', found int


139-139: SyntaxError: Expected ',', found ':'


139-139: SyntaxError: Expected ':', found ','


140-140: SyntaxError: Expected ',', found '=='


140-140: SyntaxError: Expected ',', found '=='


140-140: SyntaxError: Expected ',', found '=='


140-140: SyntaxError: Expected ',', found '='


142-142: SyntaxError: Expected ',', found '>>'


142-142: SyntaxError: Expected ',', found '>>'


142-142: SyntaxError: Expected ',', found '>>'


142-142: SyntaxError: Expected ',', found '>'


142-142: SyntaxError: Expected ':', found name


142-142: SyntaxError: Expected ',', found ':'


142-142: SyntaxError: Expected ',', found name


142-142: SyntaxError: Expected ',', found name


142-142: SyntaxError: Expected ',', found name


142-142: SyntaxError: Expected ',', found name


142-142: SyntaxError: Expected ',', found name


143-143: SyntaxError: Expected ',', found int


148-148: SyntaxError: Expected ',', found '<<'


148-148: SyntaxError: Expected ',', found '<<'


148-148: SyntaxError: Expected ',', found '<<'


148-148: SyntaxError: Expected ',', found '<'


149-149: SyntaxError: Expected ':', found int


149-149: SyntaxError: Expected ',', found ':'


149-149: SyntaxError: Expected ':', found ','


150-150: SyntaxError: Expected ',', found '=='


150-150: SyntaxError: Expected ',', found '=='


150-150: SyntaxError: Expected ',', found '=='


150-150: SyntaxError: Expected ',', found '='


152-152: SyntaxError: Expected ',', found '>>'


152-152: SyntaxError: Expected ',', found '>>'


152-152: SyntaxError: Expected ',', found '>>'


152-152: SyntaxError: Expected ',', found '>'


152-152: SyntaxError: Expected ':', found name


152-152: SyntaxError: Expected ',', found ':'


152-152: SyntaxError: Expected ',', found name


152-152: SyntaxError: Expected ',', found name


152-152: SyntaxError: Expected ',', found name


152-152: SyntaxError: Expected ',', found name


152-152: SyntaxError: Expected ',', found name


332-332: SyntaxError: Expected ',', found '<<'


332-332: SyntaxError: Expected ',', found '<<'


332-332: SyntaxError: Expected ',', found '<<'


332-332: SyntaxError: Expected ',', found '<'


333-333: SyntaxError: Expected ':', found int


333-333: SyntaxError: Expected ',', found ':'


333-333: SyntaxError: Expected ':', found ','


334-334: SyntaxError: Expected ',', found '=='


334-334: SyntaxError: Expected ',', found '=='


334-334: SyntaxError: Expected ',', found '=='


334-334: SyntaxError: Expected ',', found '='


335-335: SyntaxError: Expected ',', found '>>'


335-335: SyntaxError: Expected ',', found '>>'


335-335: SyntaxError: Expected ',', found '>>'


335-335: SyntaxError: Expected ',', found '>'


335-335: SyntaxError: Expected ':', found name


335-335: SyntaxError: Expected ',', found ':'


335-335: SyntaxError: Expected ',', found name


335-335: SyntaxError: Expected ',', found name


335-335: SyntaxError: Expected ',', found name


335-335: SyntaxError: Expected ',', found name


335-335: SyntaxError: Expected ',', found name


1196-1196: SyntaxError: Expected ',', found '<<'


1196-1196: SyntaxError: Expected ',', found '<<'


1196-1196: SyntaxError: Expected ',', found '<<'


1196-1196: SyntaxError: Expected ',', found '<'


1197-1197: SyntaxError: Expected ':', found int


1197-1197: SyntaxError: Expected ',', found ':'


1197-1197: SyntaxError: Expected ':', found ','


1198-1198: SyntaxError: Expected ',', found '=='


1198-1198: SyntaxError: Expected ',', found '=='


1198-1198: SyntaxError: Expected ',', found '=='


1198-1198: SyntaxError: Expected ',', found '='


1199-1199: SyntaxError: Expected ',', found '>>'


1199-1199: SyntaxError: Expected ',', found '>>'


1199-1199: SyntaxError: Expected ',', found '>>'


1199-1199: SyntaxError: Expected ',', found '>'


1199-1199: SyntaxError: Expected ':', found name


1199-1199: SyntaxError: Expected ',', found ':'


1199-1199: SyntaxError: Expected ',', found name


1199-1199: SyntaxError: Expected ',', found name


1199-1199: SyntaxError: Expected ',', found name


1199-1199: SyntaxError: Expected ',', found name


1199-1199: SyntaxError: Expected ',', found name

holidays/countries/ethiopia.py

17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


21-21: SyntaxError: Expected a statement


21-21: SyntaxError: Expected a statement


21-21: SyntaxError: Expected a statement


21-21: SyntaxError: Expected a statement


21-22: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Simple statements must be separated by newlines or semicolons


24-24: SyntaxError: Expected ',', found ':'


24-24: SyntaxError: Expected ',', found name


24-24: SyntaxError: Expected ',', found name


24-24: SyntaxError: Expected ',', found name


24-24: SyntaxError: Expected ',', found name


24-24: SyntaxError: Expected ',', found name


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


49-49: SyntaxError: Expected a statement


51-51: SyntaxError: Unexpected indentation


55-56: SyntaxError: Expected an indented block after function definition


56-56: SyntaxError: Expected a statement


56-56: SyntaxError: Expected a statement


56-56: SyntaxError: Expected a statement


56-56: SyntaxError: Expected a statement


56-57: SyntaxError: Expected a statement


57-57: SyntaxError: Unexpected indentation


60-61: SyntaxError: Expected an indented block after function definition


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Simple statements must be separated by newlines or semicolons


61-61: SyntaxError: Expected ',', found ':'


61-61: SyntaxError: Expected ',', found name


61-61: SyntaxError: Expected ',', found name


61-61: SyntaxError: Expected ',', found name


61-61: SyntaxError: Expected ',', found name


61-61: SyntaxError: Expected ',', found name


93-93: SyntaxError: Expected an indented block after function definition


93-93: SyntaxError: Expected a statement


93-93: SyntaxError: Expected a statement


93-93: SyntaxError: Expected a statement


127-127: SyntaxError: Expected a statement


127-127: SyntaxError: Expected a statement


127-127: SyntaxError: Expected a statement


127-127: SyntaxError: Expected a statement


127-128: SyntaxError: Expected a statement


128-128: SyntaxError: Unexpected indentation


159-160: SyntaxError: Expected an indented block after if statement


161-161: SyntaxError: Expected a statement


161-161: SyntaxError: Expected a statement


161-161: SyntaxError: Expected a statement


161-161: SyntaxError: Expected a statement


161-161: SyntaxError: Simple statements must be separated by newlines or semicolons


161-161: SyntaxError: Expected ',', found ':'


161-161: SyntaxError: Expected ',', found name


161-161: SyntaxError: Expected ',', found name


161-161: SyntaxError: Expected ',', found name


161-161: SyntaxError: Expected ',', found name


161-161: SyntaxError: Expected ',', found name


162-162: SyntaxError: Unexpected indentation


168-168: SyntaxError: Expected a statement


168-168: SyntaxError: Expected a statement


168-168: SyntaxError: Expected a statement


168-168: SyntaxError: Expected a statement


184-184: SyntaxError: Expected a statement


184-184: SyntaxError: Expected a statement


184-184: SyntaxError: Expected a statement


184-184: SyntaxError: Expected a statement


184-185: SyntaxError: Expected a statement


185-185: SyntaxError: Unexpected indentation


192-192: SyntaxError: Expected a statement


192-192: SyntaxError: Expected a statement


192-192: SyntaxError: Expected a statement


192-192: SyntaxError: Expected a statement


192-192: SyntaxError: Simple statements must be separated by newlines or semicolons


192-192: SyntaxError: Expected ',', found ':'


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found name


192-192: SyntaxError: Expected ',', found name


211-211: SyntaxError: Expected ',', found '<<'


211-211: SyntaxError: Expected ',', found '<<'


211-211: SyntaxError: Expected ',', found '<<'


211-211: SyntaxError: Expected ',', found '<'


212-212: SyntaxError: Expected ':', found int


212-212: SyntaxError: Expected ',', found ':'


212-212: SyntaxError: Expected ':', found ','


213-213: SyntaxError: Expected ',', found '=='


213-213: SyntaxError: Expected ',', found '=='


213-213: SyntaxError: Expected ',', found '=='


213-213: SyntaxError: Expected ',', found '='


214-214: SyntaxError: Expected ',', found '>>'


214-214: SyntaxError: Expected ',', found '>>'


214-214: SyntaxError: Expected ',', found '>>'


214-214: SyntaxError: Expected ',', found '>'


214-214: SyntaxError: Expected ':', found name


214-214: SyntaxError: Expected ',', found ':'


214-214: SyntaxError: Expected ',', found name


214-214: SyntaxError: Expected ',', found name


214-214: SyntaxError: Expected ',', found name


214-214: SyntaxError: Expected ',', found name


214-214: SyntaxError: Expected ',', found name


225-225: SyntaxError: Expected ',', found '<<'


225-225: SyntaxError: Expected ',', found '<<'


225-225: SyntaxError: Expected ',', found '<<'


225-225: SyntaxError: Expected ',', found '<'


226-226: SyntaxError: Expected ':', found int


226-226: SyntaxError: Expected ',', found ':'


226-226: SyntaxError: Expected ':', found ','


227-227: SyntaxError: Expected ',', found '=='


227-227: SyntaxError: Expected ',', found '=='


227-227: SyntaxError: Expected ',', found '=='


227-227: SyntaxError: Expected ',', found '='


228-228: SyntaxError: Expected ',', found '>>'


228-228: SyntaxError: Expected ',', found '>>'


228-228: SyntaxError: Expected ',', found '>>'


228-228: SyntaxError: Expected ',', found '>'


228-228: SyntaxError: Expected ':', found name


228-228: SyntaxError: Expected ',', found ':'


228-228: SyntaxError: Expected ',', found name


228-228: SyntaxError: Expected ',', found name


228-228: SyntaxError: Expected ',', found name


228-228: SyntaxError: Expected ',', found name


228-228: SyntaxError: Expected ',', found name


238-238: SyntaxError: Expected ',', found '<<'


238-238: SyntaxError: Expected ',', found '<<'


238-238: SyntaxError: Expected ',', found '<<'


238-238: SyntaxError: Expected ',', found '<'


239-239: SyntaxError: Expected ':', found int


239-239: SyntaxError: Expected ',', found ':'


239-239: SyntaxError: Expected ':', found ','


240-240: SyntaxError: Expected ',', found '=='


240-240: SyntaxError: Expected ',', found '=='


240-240: SyntaxError: Expected ',', found '=='


240-240: SyntaxError: Expected ',', found '='


241-241: SyntaxError: Expected ',', found '>>'


241-241: SyntaxError: Expected ',', found '>>'


241-241: SyntaxError: Expected ',', found '>>'


241-241: SyntaxError: Expected ',', found '>'


241-241: SyntaxError: Expected ':', found name


241-241: SyntaxError: Expected ',', found ':'


241-241: SyntaxError: Expected ',', found name


241-241: SyntaxError: Expected ',', found name


241-241: SyntaxError: Expected ',', found name


241-241: SyntaxError: Expected ',', found name


241-241: SyntaxError: Expected ',', found name

holidays/calendars/chinese.py

19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


19-19: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-25: SyntaxError: Expected a statement


25-25: SyntaxError: Expected a statement


25-25: SyntaxError: Expected a statement


25-25: SyntaxError: Expected a statement


25-25: SyntaxError: Expected a statement


25-25: SyntaxError: Simple statements must be separated by newlines or semicolons


25-25: SyntaxError: Expected ',', found ':'


25-25: SyntaxError: Expected ',', found name


25-25: SyntaxError: Expected ',', found name


25-25: SyntaxError: Expected ',', found name


25-25: SyntaxError: Expected ',', found name


25-25: SyntaxError: Expected ',', found name


235-235: SyntaxError: Expected ',', found '<<'


235-235: SyntaxError: Expected ',', found '<<'


235-235: SyntaxError: Expected ',', found '<<'


235-235: SyntaxError: Expected ',', found '<'


236-236: SyntaxError: Expected ':', found int


236-236: SyntaxError: Expected ',', found ':'


236-236: SyntaxError: Expected ':', found ','


237-237: SyntaxError: Expected ',', found '=='


237-237: SyntaxError: Expected ',', found '=='


237-237: SyntaxError: Expected ',', found '=='


237-237: SyntaxError: Expected ',', found '='


238-238: SyntaxError: Expected ',', found '>>'


238-238: SyntaxError: Expected ',', found '>>'


238-238: SyntaxError: Expected ',', found '>>'


238-238: SyntaxError: Expected ',', found '>'


238-238: SyntaxError: Expected ':', found name


238-238: SyntaxError: Expected ',', found ':'


238-238: SyntaxError: Expected ',', found name


238-238: SyntaxError: Expected ',', found name


238-238: SyntaxError: Expected ',', found name


238-238: SyntaxError: Expected ',', found name


238-238: SyntaxError: Expected ',', found name


441-441: SyntaxError: Expected ',', found '<<'


441-441: SyntaxError: Expected ',', found '<<'


441-441: SyntaxError: Expected ',', found '<<'


441-441: SyntaxError: Expected ',', found '<'


442-442: SyntaxError: Expected ':', found int


442-442: SyntaxError: Expected ',', found ':'


442-442: SyntaxError: Expected ':', found ','


443-443: SyntaxError: Expected ',', found '=='


443-443: SyntaxError: Expected ',', found '=='


443-443: SyntaxError: Expected ',', found '=='


443-443: SyntaxError: Expected ',', found '='


444-444: SyntaxError: Expected ',', found '>>'


444-444: SyntaxError: Expected ',', found '>>'


444-444: SyntaxError: Expected ',', found '>>'


444-444: SyntaxError: Expected ',', found '>'


444-444: SyntaxError: Expected ':', found name


444-444: SyntaxError: Expected ',', found ':'


444-444: SyntaxError: Expected ',', found name


444-444: SyntaxError: Expected ',', found name


444-444: SyntaxError: Expected ',', found name


444-444: SyntaxError: Expected ',', found name


444-444: SyntaxError: Expected ',', found name


647-647: SyntaxError: Expected ',', found '<<'


647-647: SyntaxError: Expected ',', found '<<'


647-647: SyntaxError: Expected ',', found '<<'


647-647: SyntaxError: Expected ',', found '<'


648-648: SyntaxError: Expected ':', found int


648-648: SyntaxError: Expected ',', found ':'


648-648: SyntaxError: Expected ':', found ','


649-649: SyntaxError: Expected ',', found '=='


649-649: SyntaxError: Expected ',', found '=='


649-649: SyntaxError: Expected ',', found '=='


649-649: SyntaxError: Expected ',', found '='


650-650: SyntaxError: Expected ',', found '>>'


650-650: SyntaxError: Expected ',', found '>>'


650-650: SyntaxError: Expected ',', found '>>'


650-650: SyntaxError: Expected ',', found '>'


650-650: SyntaxError: Expected ':', found name


650-650: SyntaxError: Expected ',', found ':'


650-650: SyntaxError: Expected ',', found name


650-650: SyntaxError: Expected ',', found name


650-650: SyntaxError: Expected ',', found name


650-650: SyntaxError: Expected ',', found name


650-650: SyntaxError: Expected ',', found name


853-853: SyntaxError: Expected ',', found '<<'


853-853: SyntaxError: Expected ',', found '<<'


853-853: SyntaxError: Expected ',', found '<<'


853-853: SyntaxError: Expected ',', found '<'


854-854: SyntaxError: Expected ':', found int


854-854: SyntaxError: Expected ',', found ':'


854-854: SyntaxError: Expected ':', found ','


855-855: SyntaxError: Expected ',', found '=='


855-855: SyntaxError: Expected ',', found '=='


855-855: SyntaxError: Expected ',', found '=='


855-855: SyntaxError: Expected ',', found '='


856-856: SyntaxError: Expected ',', found '>>'


856-856: SyntaxError: Expected ',', found '>>'


856-856: SyntaxError: Expected ',', found '>>'


856-856: SyntaxError: Expected ',', found '>'


856-856: SyntaxError: Expected ':', found name


856-856: SyntaxError: Expected ',', found ':'


856-856: SyntaxError: Expected ',', found name


856-856: SyntaxError: Expected ',', found name


856-856: SyntaxError: Expected ',', found name


856-856: SyntaxError: Expected ',', found name


856-856: SyntaxError: Expected ',', found name


875-875: SyntaxError: Expected ',', found '<<'


875-875: SyntaxError: Expected ',', found '<<'


875-875: SyntaxError: Expected ',', found '<<'


875-875: SyntaxError: Expected ',', found '<'


876-876: SyntaxError: Expected ':', found int


876-876: SyntaxError: Expected ',', found ':'


876-876: SyntaxError: Expected ':', found ','


877-877: SyntaxError: Expected ',', found '=='


877-877: SyntaxError: Expected ',', found '=='


877-877: SyntaxError: Expected ',', found '=='


877-877: SyntaxError: Expected ',', found '='


879-879: SyntaxError: Expected ',', found '>>'


879-879: SyntaxError: Expected ',', found '>>'


879-879: SyntaxError: Expected ',', found '>>'


879-879: SyntaxError: Expected ',', found '>'


879-879: SyntaxError: Expected ':', found name


879-879: SyntaxError: Expected ',', found ':'


879-879: SyntaxError: Expected ',', found name


879-879: SyntaxError: Expected ',', found name


879-879: SyntaxError: Expected ',', found name


879-879: SyntaxError: Expected ',', found name


879-879: SyntaxError: Expected ',', found name


1063-1063: SyntaxError: Expected ',', found '<<'


1063-1063: SyntaxError: Expected ',', found '<<'


1063-1063: SyntaxError: Expected ',', found '<<'


1063-1063: SyntaxError: Expected ',', found '<'


1064-1064: SyntaxError: Expected ':', found int


1064-1064: SyntaxError: Expected ',', found ':'


1064-1064: SyntaxError: Expected ':', found ','


1065-1065: SyntaxError: Expected ',', found '=='


1065-1065: SyntaxError: Expected ',', found '=='


1065-1065: SyntaxError: Expected ',', found '=='


1065-1065: SyntaxError: Expected ',', found '='


1066-1066: SyntaxError: Expected ',', found '>>'


1066-1066: SyntaxError: Expected ',', found '>>'


1066-1066: SyntaxError: Expected ',', found '>>'


1066-1066: SyntaxError: Expected ',', found '>'


1066-1066: SyntaxError: Expected ':', found name


1066-1066: SyntaxError: Expected ',', found ':'


1066-1066: SyntaxError: Expected ',', found name


1066-1066: SyntaxError: Expected ',', found name


1066-1066: SyntaxError: Expected ',', found name


1066-1066: SyntaxError: Expected ',', found name


1066-1066: SyntaxError: Expected ',', found name


1258-1258: SyntaxError: Expected ',', found '<<'


1258-1258: SyntaxError: Expected ',', found '<<'


1258-1258: SyntaxError: Expected ',', found '<<'


1258-1258: SyntaxError: Expected ',', found '<'


1259-1259: SyntaxError: Expected ':', found int


1259-1259: SyntaxError: Expected ',', found ':'


1259-1259: SyntaxError: Expected ':', found ','


1260-1260: SyntaxError: Expected ',', found '=='


1260-1260: SyntaxError: Expected ',', found '=='


1260-1260: SyntaxError: Expected ',', found '=='


1260-1260: SyntaxError: Expected ',', found '='


1262-1262: SyntaxError: Expected ',', found '>>'


1262-1262: SyntaxError: Expected ',', found '>>'


1262-1262: SyntaxError: Expected ',', found '>>'


1262-1262: SyntaxError: Expected ',', found '>'


1262-1262: SyntaxError: Expected ':', found name


1262-1262: SyntaxError: Expected ',', found ':'


1262-1262: SyntaxError: Expected ',', found name


1262-1262: SyntaxError: Expected ',', found name


1262-1262: SyntaxError: Expected ',', found name


1262-1262: SyntaxError: Expected ',', found name


1262-1262: SyntaxError: Expected ',', found name


1273-1273: SyntaxError: Expected ',', found '<<'


1273-1273: SyntaxError: Expected ',', found '<<'


1273-1273: SyntaxError: Expected ',', found '<<'


1273-1273: SyntaxError: Expected ',', found '<'


1363-1363: SyntaxError: Expected a statement


1363-1363: SyntaxError: Expected a statement


1363-1363: SyntaxError: Expected a statement


1363-1363: SyntaxError: Expected a statement


1363-1364: SyntaxError: Expected a statement


1364-1364: SyntaxError: Unexpected indentation


1364-1364: SyntaxError: Expected a statement


1364-1365: SyntaxError: Expected a statement


1374-1374: SyntaxError: Expected a statement


1374-1374: SyntaxError: Expected a statement


1374-1374: SyntaxError: Expected a statement


1374-1374: SyntaxError: Expected a statement


1374-1374: SyntaxError: Simple statements must be separated by newlines or semicolons


1374-1374: SyntaxError: Expected ',', found ':'


1374-1374: SyntaxError: Expected ',', found name


1374-1374: SyntaxError: Expected ',', found name


1374-1374: SyntaxError: Expected ',', found name


1374-1374: SyntaxError: Expected ',', found name


1374-1374: SyntaxError: Expected ',', found name


1376-1376: SyntaxError: Unexpected indentation


1382-1382: SyntaxError: Expected a statement


1382-1382: SyntaxError: Expected a statement


1382-1382: SyntaxError: Expected a statement


1382-1382: SyntaxError: Expected a statement


1391-1391: SyntaxError: Expected a statement


1391-1391: SyntaxError: Expected a statement


1391-1391: SyntaxError: Expected a statement


1391-1391: SyntaxError: Expected a statement


1391-1392: SyntaxError: Expected a statement


1392-1392: SyntaxError: Unexpected indentation


1400-1400: SyntaxError: Expected a statement


1400-1400: SyntaxError: Expected a statement


1400-1400: SyntaxError: Expected a statement


1400-1400: SyntaxError: Expected a statement


1400-1400: SyntaxError: Simple statements must be separated by newlines or semicolons


1400-1400: SyntaxError: Expected ',', found ':'


1400-1400: SyntaxError: Expected ',', found name


1400-1400: SyntaxError: Expected ',', found name


1400-1400: SyntaxError: Expected ',', found name


1400-1400: SyntaxError: Expected ',', found name


1400-1400: SyntaxError: Expected ',', found name

tests/countries/test_finland.py

305-305: SyntaxError: Expected a statement


305-305: SyntaxError: Expected a statement


305-305: SyntaxError: Expected a statement


305-305: SyntaxError: Expected a statement


306-306: SyntaxError: Unexpected indentation


307-307: SyntaxError: Expected a statement


307-307: SyntaxError: Expected a statement


307-307: SyntaxError: Expected a statement


307-307: SyntaxError: Expected a statement


307-308: SyntaxError: Expected a statement


308-308: SyntaxError: Unexpected indentation


309-309: SyntaxError: Expected a statement


309-309: SyntaxError: Expected a statement


309-309: SyntaxError: Expected a statement


309-309: SyntaxError: Expected a statement


309-309: SyntaxError: Simple statements must be separated by newlines or semicolons


309-309: SyntaxError: Expected ',', found ':'


309-309: SyntaxError: Expected ',', found name


309-309: SyntaxError: Expected ',', found name


309-309: SyntaxError: Expected ',', found name


309-309: SyntaxError: Expected ',', found name


309-309: SyntaxError: Expected ',', found name

holidays/calendars/buddhist.py

149-149: SyntaxError: Expected ',', found '<<'


149-149: SyntaxError: Expected ',', found '<<'


149-149: SyntaxError: Expected ',', found '<<'


149-149: SyntaxError: Expected ',', found '<'


150-150: SyntaxError: Expected ':', found int


150-150: SyntaxError: Expected ',', found ':'


150-150: SyntaxError: Expected ':', found ','


151-151: SyntaxError: Expected ',', found '=='


151-151: SyntaxError: Expected ',', found '=='


151-151: SyntaxError: Expected ',', found '=='


151-151: SyntaxError: Expected ',', found '='


153-153: SyntaxError: Expected ',', found '>>'


153-153: SyntaxError: Expected ',', found '>>'


153-153: SyntaxError: Expected ',', found '>>'


153-153: SyntaxError: Expected ',', found '>'


153-153: SyntaxError: Expected ':', found name


153-153: SyntaxError: Expected ',', found ':'


153-153: SyntaxError: Expected ',', found name


153-153: SyntaxError: Expected ',', found name


153-153: SyntaxError: Expected ',', found name


153-153: SyntaxError: Expected ',', found name


153-153: SyntaxError: Expected ',', found name


228-228: SyntaxError: Expected ',', found '<<'


228-228: SyntaxError: Expected ',', found '<<'


228-228: SyntaxError: Expected ',', found '<<'


228-228: SyntaxError: Expected ',', found '<'


229-229: SyntaxError: Expected ':', found int


229-229: SyntaxError: Expected ',', found ':'


229-229: SyntaxError: Expected ':', found ','


230-230: SyntaxError: Expected ',', found '=='


230-230: SyntaxError: Expected ',', found '=='


230-230: SyntaxError: Expected ',', found '=='


230-230: SyntaxError: Expected ',', found '='


231-231: SyntaxError: Expected ',', found '>>'


231-231: SyntaxError: Expected ',', found '>>'


231-231: SyntaxError: Expected ',', found '>>'


231-231: SyntaxError: Expected ',', found '>'


231-231: SyntaxError: Expected ':', found name


231-231: SyntaxError: Expected ',', found ':'


231-231: SyntaxError: Expected ',', found name


231-231: SyntaxError: Expected ',', found name


231-231: SyntaxError: Expected ',', found name


231-231: SyntaxError: Expected ',', found name


231-231: SyntaxError: Expected ',', found name


359-359: SyntaxError: Expected ',', found '<<'


359-359: SyntaxError: Expected ',', found '<<'


359-359: SyntaxError: Expected ',', found '<<'


359-359: SyntaxError: Expected ',', found '<'


360-360: SyntaxError: Expected ':', found int


360-360: SyntaxError: Expected ',', found ':'


360-360: SyntaxError: Expected ':', found ','


361-361: SyntaxError: Expected ',', found '=='


361-361: SyntaxError: Expected ',', found '=='


361-361: SyntaxError: Expected ',', found '=='


361-361: SyntaxError: Expected ',', found '='


363-363: SyntaxError: Expected ',', found '>>'


363-363: SyntaxError: Expected ',', found '>>'


363-363: SyntaxError: Expected ',', found '>>'


363-363: SyntaxError: Expected ',', found '>'


363-363: SyntaxError: Expected ':', found name


363-363: SyntaxError: Expected ',', found ':'


363-363: SyntaxError: Expected ',', found name


363-363: SyntaxError: Expected ',', found name


363-363: SyntaxError: Expected ',', found name


363-363: SyntaxError: Expected ',', found name


363-363: SyntaxError: Expected ',', found name


438-438: SyntaxError: Expected ',', found '<<'


438-438: SyntaxError: Expected ',', found '<<'


438-438: SyntaxError: Expected ',', found '<<'


438-438: SyntaxError: Expected ',', found '<'


439-439: SyntaxError: Expected ':', found int


439-439: SyntaxError: Expected ',', found ':'


439-439: SyntaxError: Expected ':', found ','


440-440: SyntaxError: Expected ',', found '=='


440-440: SyntaxError: Expected ',', found '=='


440-440: SyntaxError: Expected ',', found '=='


440-440: SyntaxError: Expected ',', found '='


441-441: SyntaxError: Expected ',', found '>>'


441-441: SyntaxError: Expected ',', found '>>'


441-441: SyntaxError: Expected ',', found '>>'


441-441: SyntaxError: Expected ',', found '>'


441-441: SyntaxError: Expected ':', found name


441-441: SyntaxError: Expected ',', found ':'


441-441: SyntaxError: Expected ',', found name


441-441: SyntaxError: Expected ',', found name


441-441: SyntaxError: Expected ',', found name


441-441: SyntaxError: Expected ',', found name


441-441: SyntaxError: Expected ',', found name

tests/countries/test_ethiopia.py

15-15: SyntaxError: Expected a statement


15-15: SyntaxError: Expected a statement


15-15: SyntaxError: Expected a statement


15-15: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-17: SyntaxError: Expected a statement


17-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Expected a statement


18-18: SyntaxError: Simple statements must be separated by newlines or semicolons


18-18: SyntaxError: Expected ',', found ':'


18-18: SyntaxError: Expected ',', found name


18-18: SyntaxError: Expected ',', found name


18-18: SyntaxError: Expected ',', found name


18-18: SyntaxError: Expected ',', found name


18-18: SyntaxError: Expected ',', found name


25-26: SyntaxError: Expected an indented block after function definition


26-26: SyntaxError: Expected a statement


26-26: SyntaxError: Expected a statement


26-26: SyntaxError: Expected a statement


26-26: SyntaxError: Expected a statement


27-27: SyntaxError: Unexpected indentation


31-31: SyntaxError: Expected a statement


31-31: SyntaxError: Expected a statement


31-31: SyntaxError: Expected a statement


31-31: SyntaxError: Expected a statement


31-32: SyntaxError: Expected a statement


32-32: SyntaxError: Unexpected indentation


33-33: SyntaxError: Expected a statement


33-33: SyntaxError: Expected a statement


33-33: SyntaxError: Expected a statement


33-33: SyntaxError: Expected a statement


33-33: SyntaxError: Simple statements must be separated by newlines or semicolons


33-33: SyntaxError: Expected ',', found ':'


33-33: SyntaxError: Expected ',', found name


33-33: SyntaxError: Expected ',', found name


33-33: SyntaxError: Expected ',', found name


33-33: SyntaxError: Expected ',', found name


33-33: SyntaxError: Expected ',', found name


35-35: SyntaxError: Unexpected indentation


38-39: SyntaxError: Expected an indented block after function definition


39-39: SyntaxError: Expected a statement


39-39: SyntaxError: Expected a statement


39-39: SyntaxError: Expected a statement


39-39: SyntaxError: Expected a statement


59-59: SyntaxError: Expected a statement


59-59: SyntaxError: Expected a statement


59-59: SyntaxError: Expected a statement


59-59: SyntaxError: Expected a statement


59-60: SyntaxError: Expected a statement


60-60: SyntaxError: Unexpected indentation


62-62: SyntaxError: unindent does not match any outer indentation level


65-65: SyntaxError: unindent does not match any outer indentation level


74-74: SyntaxError: unindent does not match any outer indentation level


77-77: SyntaxError: unindent does not match any outer indentation level


79-79: SyntaxError: Expected a statement


79-79: SyntaxError: Expected a statement


79-79: SyntaxError: Expected a statement


79-79: SyntaxError: Expected a statement


79-79: SyntaxError: Simple statements must be separated by newlines or semicolons


79-79: SyntaxError: Expected ',', found ':'


79-79: SyntaxError: Expected ',', found name


79-79: SyntaxError: Expected ',', found name


79-79: SyntaxError: Expected ',', found name


79-79: SyntaxError: Expected ',', found name


79-79: SyntaxError: Expected ',', found name


89-89: SyntaxError: Expected ',', found '<<'


89-89: SyntaxError: Expected ',', found '<<'


89-89: SyntaxError: Expected ',', found '<<'


89-89: SyntaxError: Expected ',', found '<'


90-90: SyntaxError: Expected ',', found string


94-94: SyntaxError: unindent does not match any outer indentation level


96-96: SyntaxError: Expected a statement


96-96: SyntaxError: Expected a statement


96-96: SyntaxError: Expected a statement


96-96: SyntaxError: Expected a statement


96-97: SyntaxError: Expected a statement


97-97: SyntaxError: Unexpected indentation


97-97: SyntaxError: Expected a statement


97-98: SyntaxError: Expected a statement


100-100: SyntaxError: unindent does not match any outer indentation level


102-102: SyntaxError: Expected a statement


102-102: SyntaxError: Expected a statement


102-102: SyntaxError: Expected a statement


102-102: SyntaxError: Expected a statement


102-102: SyntaxError: Simple statements must be separated by newlines or semicolons


102-102: SyntaxError: Expected ',', found ':'


102-102: SyntaxError: Expected ',', found name


102-102: SyntaxError: Expected ',', found name


102-102: SyntaxError: Expected ',', found name


102-102: SyntaxError: Expected ',', found name


102-102: SyntaxError: Expected ',', found name


112-112: SyntaxError: Expected ',', found '<<'


112-112: SyntaxError: Expected ',', found '<<'


112-112: SyntaxError: Expected ',', found '<<'


112-112: SyntaxError: Expected ',', found '<'


164-164: SyntaxError: Expected ',', found '=='


164-164: SyntaxError: Expected ',', found '=='


164-164: SyntaxError: Expected ',', found '=='


164-164: SyntaxError: Expected ',', found '='


168-168: SyntaxError: unindent does not match any outer indentation level


171-171: SyntaxError: unindent does not match any outer indentation level


176-176: SyntaxError: unindent does not match any outer indentation level


181-181: SyntaxError: unindent does not match any outer indentation level


190-190: SyntaxError: unindent does not match any outer indentation level


199-199: SyntaxError: unindent does not match any outer indentation level


209-209: SyntaxError: unindent does not match any outer indentation level


214-214: SyntaxError: unindent does not match any outer indentation level


217-217: SyntaxError: Expected ',', found '>>'


217-217: SyntaxError: Expected ',', found '>>'


217-217: SyntaxError: Expected ',', found '>>'


217-217: SyntaxError: Expected ',', found '>'


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found ':'


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


217-217: SyntaxError: Expected ',', found name


218-218: SyntaxError: Expected ',', found string


224-224: SyntaxError: Expected ',', found '<<'


224-224: SyntaxError: Expected ',', found '<<'


224-224: SyntaxError: Expected ',', found '<<'


224-224: SyntaxError: Expected ',', found '<'


234-234: SyntaxError: Expected ',', found '=='


234-234: SyntaxError: Expected ',', found '=='


234-234: SyntaxError: Expected ',', found '=='


234-234: SyntaxError: Expected ',', found '='


237-237: SyntaxError: unindent does not match any outer indentation level


240-240: SyntaxError: Expected ',', found '>>'


240-240: SyntaxError: Expected ',', found '>>'


240-240: SyntaxError: Expected ',', found '>>'


240-240: SyntaxError: Expected ',', found '>'


240-240: SyntaxError: Expected ',', found name


240-240: SyntaxError: Expected ',', found ':'


240-240: SyntaxError: Expected ',', found name


240-240: SyntaxError: Expected ',', found name


240-240: SyntaxError: Expected ',', found name


240-240: SyntaxError: Expected ',', found name


240-240: SyntaxError: Expected ',', found name


241-241: SyntaxError: Expected ',', found string


247-247: SyntaxError: Expected ',', found '<<'


247-247: SyntaxError: Expected ',', found '<<'


247-247: SyntaxError: Expected ',', found '<<'


247-247: SyntaxError: Expected ',', found '<'


256-256: SyntaxError: Expected ',', found '=='


256-256: SyntaxError: Expected ',', found '=='


256-256: SyntaxError: Expected ',', found '=='


256-256: SyntaxError: Expected ',', found '='


259-259: SyntaxError: unindent does not match any outer indentation level


262-262: SyntaxError: Expected ',', found '>>'


262-262: SyntaxError: Expected ',', found '>>'


262-262: SyntaxError: Expected ',', found '>>'


262-262: SyntaxError: Expected ',', found '>'


262-262: SyntaxError: Expected ',', found name


262-262: SyntaxError: Expected ',', found ':'


262-262: SyntaxError: Expected ',', found name


262-262: SyntaxError: Expected ',', found name


262-262: SyntaxError: Expected ',', found name


262-262: SyntaxError: Expected ',', found name


262-262: SyntaxError: Expected ',', found name


263-263: SyntaxError: Expected ',', found string


269-269: SyntaxError: Expected ',', found '<<'


269-269: SyntaxError: Expected ',', found '<<'


269-269: SyntaxError: Expected ',', found '<<'


269-269: SyntaxError: Expected ',', found '<'


349-349: SyntaxError: Expected ',', found '=='


349-349: SyntaxError: Expected ',', found '=='


349-349: SyntaxError: Expected ',', found '=='


349-349: SyntaxError: Expected ',', found '='


352-352: SyntaxError: unindent does not match any outer indentation level


369-369: SyntaxError: unindent does not match any outer indentation level


385-385: SyntaxError: Expected ',', found '>>'


385-385: SyntaxError: Expected ',', found '>>'


385-385: SyntaxError: Expected ',', found '>>'


385-385: SyntaxError: Expected ',', found '>'


385-385: SyntaxError: Expected ',', found name


385-385: SyntaxError: Expected ',', found ':'


385-385: SyntaxError: Expected ',', found name


385-385: SyntaxError: Expected ',', found name


385-385: SyntaxError: Expected ',', found name


385-385: SyntaxError: Expected ',', found name


385-385: SyntaxError: Expected ',', found name


388-388: SyntaxError: unindent does not match any outer indentation level


392-392: SyntaxError: Expected ',', found '<<'


392-392: SyntaxError: Expected ',', found '<<'


392-392: SyntaxError: Expected ',', found '<<'


392-392: SyntaxError: Expected ',', found '<'


402-402: SyntaxError: Expected ',', found '=='


402-402: SyntaxError: Expected ',', found '=='


402-402: SyntaxError: Expected ',', found '=='


402-402: SyntaxError: Expected ',', found '='


411-411: SyntaxError: Expected ',', found '>>'


411-411: SyntaxError: Expected ',', found '>>'


411-411: SyntaxError: Expected ',', found '>>'


411-411: SyntaxError: Expected ',', found '>'


411-411: SyntaxError: Expected ',', found name


411-411: SyntaxError: Expected ',', found ':'


411-411: SyntaxError: Expected ',', found name


411-411: SyntaxError: Expected ',', found name


411-411: SyntaxError: Expected ',', found name


411-411: SyntaxError: Expected ',', found name


411-411: SyntaxError: Expected ',', found name


416-416: SyntaxError: Expected ',', found '<<'


416-416: SyntaxError: Expected ',', found '<<'


416-416: SyntaxError: Expected ',', found '<<'


416-416: SyntaxError: Expected ',', found '<'


418-418: SyntaxError: Expected ',', found '=='


418-418: SyntaxError: Expected ',', found '=='


418-418: SyntaxError: Expected ',', found '=='


418-418: SyntaxError: Expected ',', found '='


419-419: SyntaxError: Expected ',', found '>>'


419-419: SyntaxError: Expected ',', found '>>'


419-419: SyntaxError: Expected ',', found '>>'


419-419: SyntaxError: Expected ',', found '>'


419-419: SyntaxError: Expected ',', found name


419-419: SyntaxError: Expected ',', found ':'


419-419: SyntaxError: Expected ',', found name


419-419: SyntaxError: Expected ',', found name


419-419: SyntaxError: Expected ',', found name


419-419: SyntaxError: Expected ',', found name


419-419: SyntaxError: Expected ',', found name

scripts/calendar/asian_generator.py

44-44: SyntaxError: Expected an expression


44-44: SyntaxError: Expected an expression


44-44: SyntaxError: Expected an expression


44-44: SyntaxError: Expected an expression


45-45: SyntaxError: Expected ')', found int


45-45: SyntaxError: Invalid assignment target


46-46: SyntaxError: Expected an expression


46-46: SyntaxError: Expected an expression


46-46: SyntaxError: Expected an expression


48-48: SyntaxError: Expected an expression


48-48: SyntaxError: Expected an expression


48-48: SyntaxError: Expected an expression


48-48: SyntaxError: Expected an expression


48-48: SyntaxError: Expected ',', found name


48-48: SyntaxError: Expected ')', found ':'


48-48: SyntaxError: Expected a statement


48-48: SyntaxError: Simple statements must be separated by newlines or semicolons


48-48: SyntaxError: Simple statements must be separated by newlines or semicolons


48-48: SyntaxError: Simple statements must be separated by newlines or semicolons


48-48: SyntaxError: Simple statements must be separated by newlines or semicolons


48-48: SyntaxError: Simple statements must be separated by newlines or semicolons


48-48: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


62-62: SyntaxError: Unexpected indentation


69-69: SyntaxError: Expected a statement


69-69: SyntaxError: Expected a statement


69-69: SyntaxError: Expected a statement


69-69: SyntaxError: Expected a statement


69-70: SyntaxError: Expected a statement


70-70: SyntaxError: Unexpected indentation


77-77: SyntaxError: Expected a statement


77-77: SyntaxError: Expected a statement


77-77: SyntaxError: Expected a statement


77-77: SyntaxError: Expected a statement


77-77: SyntaxError: Simple statements must be separated by newlines or semicolons


77-77: SyntaxError: Expected ',', found ':'


77-77: SyntaxError: Expected ',', found name


77-77: SyntaxError: Expected ',', found name


77-77: SyntaxError: Expected ',', found name


77-77: SyntaxError: Expected ',', found name


77-77: SyntaxError: Expected ',', found name


146-146: SyntaxError: Expected a statement


146-146: SyntaxError: Expected a statement


146-146: SyntaxError: Expected a statement


146-146: SyntaxError: Expected a statement


147-147: SyntaxError: Unexpected indentation


148-148: SyntaxError: Expected a statement


148-148: SyntaxError: Expected a statement


148-148: SyntaxError: Expected a statement


148-148: SyntaxError: Expected a statement


148-149: SyntaxError: Expected a statement


149-149: SyntaxError: Unexpected indentation


150-150: SyntaxError: Expected a statement


150-150: SyntaxError: Expected a statement


150-150: SyntaxError: Expected a statement


150-150: SyntaxError: Expected a statement


150-150: SyntaxError: Simple statements must be separated by newlines or semicolons


150-150: SyntaxError: Expected ',', found ':'


150-150: SyntaxError: Expected ',', found name


150-150: SyntaxError: Expected ',', found name


150-150: SyntaxError: Expected ',', found name


150-150: SyntaxError: Expected ',', found name


150-150: SyntaxError: Expected ',', found name


186-186: SyntaxError: Expected a statement


186-186: SyntaxError: Expected a statement


186-186: SyntaxError: Expected a statement


186-186: SyntaxError: Expected a statement


187-187: SyntaxError: Unexpected indentation


188-188: SyntaxError: Expected a statement


188-188: SyntaxError: Expected a statement


188-188: SyntaxError: Expected a statement


188-188: SyntaxError: Expected a statement


188-189: SyntaxError: Expected a statement


189-189: SyntaxError: Unexpected indentation


190-190: SyntaxError: Expected a statement


190-190: SyntaxError: Expected a statement


190-190: SyntaxError: Expected a statement


190-190: SyntaxError: Expected a statement


190-190: SyntaxError: Simple statements must be separated by newlines or semicolons


190-190: SyntaxError: Expected ',', found ':'


190-190: SyntaxError: Expected ',', found name


190-190: SyntaxError: Expected ',', found name


190-190: SyntaxError: Expected ',', found name


190-190: SyntaxError: Expected ',', found name


190-190: SyntaxError: Expected ',', found name


254-254: SyntaxError: Expected a statement


254-254: SyntaxError: Expected a statement


254-254: SyntaxError: Expected a statement


254-254: SyntaxError: Expected a statement


255-255: SyntaxError: Unexpected indentation


256-256: SyntaxError: Expected a statement


256-256: SyntaxError: Expected a statement


256-256: SyntaxError: Expected a statement


256-256: SyntaxError: Expected a statement


256-257: SyntaxError: Expected a statement


257-257: SyntaxError: Unexpected indentation


258-258: SyntaxError: Expected a statement


258-258: SyntaxError: Expected a statement


258-258: SyntaxError: Expected a statement


258-258: SyntaxError: Expected a statement


258-258: SyntaxError: Simple statements must be separated by newlines or semicolons


258-258: SyntaxError: Expected ',', found ':'


258-258: SyntaxError: Expected ',', found name


258-258: SyntaxError: Expected ',', found name


258-258: SyntaxError: Expected ',', found name


258-258: SyntaxError: Expected ',', found name


258-258: SyntaxError: Expected ',', found name


268-268: SyntaxError: Expected a statement


268-268: SyntaxError: Expected a statement


268-268: SyntaxError: Expected a statement


268-268: SyntaxError: Expected a statement


281-281: SyntaxError: Expected a statement


281-281: SyntaxError: Expected a statement


281-281: SyntaxError: Expected a statement


281-281: SyntaxError: Expected a statement


281-282: SyntaxError: Expected a statement


282-282: SyntaxError: Unexpected indentation


283-283: SyntaxError: unindent does not match any outer indentation level


283-283: SyntaxError: Expected a statement


283-284: SyntaxError: Expected a statement


285-285: SyntaxError: Unexpected indentation


293-293: SyntaxError: Expected a statement


293-293: SyntaxError: Expected a statement


293-293: SyntaxError: Expected a statement


293-293: SyntaxError: Expected a statement


293-293: SyntaxError: Simple statements must be separated by newlines or semicolons


293-293: SyntaxError: Expected ',', found ':'


293-293: SyntaxError: Expected ',', found name


293-293: SyntaxError: Expected ',', found name


293-293: SyntaxError: Expected ',', found name


293-293: SyntaxError: Expected ',', found name


293-293: SyntaxError: Expected ',', found name


399-399: SyntaxError: Expected a statement


399-399: SyntaxError: Expected a statement


399-399: SyntaxError: Expected a statement


399-399: SyntaxError: Expected a statement


405-405: SyntaxError: Expected a statement


405-405: SyntaxError: Expected a statement


405-405: SyntaxError: Expected a statement


405-405: SyntaxError: Expected a statement


405-406: SyntaxError: Expected a statement


406-406: SyntaxError: Expected a statement


406-406: SyntaxError: Expected a statement


406-406: SyntaxError: Expected a statement


406-406: SyntaxError: Expected a statement


406-406: SyntaxError: Simple statements must be separated by newlines or semicolons


406-406: SyntaxError: Expected ',', found ':'


406-406: SyntaxError: Expected ',', found name


406-406: SyntaxError: Expected ',', found name


406-406: SyntaxError: Expected ',', found name


406-406: SyntaxError: Expected ',', found name


406-406: SyntaxError: Expected ',', found name


434-434: SyntaxError: Expected a statement


434-434: SyntaxError: Expected a statement


434-434: SyntaxError: Expected a statement


434-434: SyntaxError: Expected a statement


435-435: SyntaxError: Unexpected indentation


436-436: SyntaxError: Expected a statement


436-436: SyntaxError: Expected a statement


436-436: SyntaxError: Expected a statement


436-436: SyntaxError: Expected a statement


436-437: SyntaxError: Expected a statement


437-437: SyntaxError: Unexpected indentation


438-438: SyntaxError: Expected a statement


438-438: SyntaxError: Expected a statement


438-438: SyntaxError: Expected a statement


438-438: SyntaxError: Expected a statement


438-438: SyntaxError: Simple statements must be separated by newlines or semicolons


438-438: SyntaxError: Expected ',', found ':'


438-438: SyntaxError: Expected ',', found name


438-438: SyntaxError: Expected ',', found name


438-438: SyntaxError: Expected ',', found name


438-438: SyntaxError: Expected ',', found name


438-438: SyntaxError: Expected ',', found name

tests/countries/test_aland_islands.py

24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


24-24: SyntaxError: Expected a statement


25-25: SyntaxError: Expected a statement


25-25: SyntaxError: Expected a statement


25-25: SyntaxError: Expected a statement


25-25: SyntaxError: Expected a statement


25-26: SyntaxError: Expected a statement


26-26: SyntaxError: Unexpected indentation


27-27: SyntaxError: Expected a statement


27-27: SyntaxError: Expected a statement


27-27: SyntaxError: Expected a statement


27-27: SyntaxError: Expected a statement


27-27: SyntaxError: Simple statements must be separated by newlines or semicolons


27-27: SyntaxError: Expected ',', found ':'


27-27: SyntaxError: Expected ',', found name


27-27: SyntaxError: Expected ',', found name


27-27: SyntaxError: Expected ',', found name


27-27: SyntaxError: Expected ',', found name


27-27: SyntaxError: Expected ',', found name


29-29: SyntaxError: Unexpected indentation


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


39-39: SyntaxError: Unexpected indentation


40-40: SyntaxError: Expected a statement


40-40: SyntaxError: Expected a statement


40-40: SyntaxError: Expected a statement


40-40: SyntaxError: Expected a statement


40-41: SyntaxError: Expected a statement


41-41: SyntaxError: Unexpected indentation


42-42: SyntaxError: Expected a statement


42-42: SyntaxError: Expected a statement


42-42: SyntaxError: Expected a statement


42-42: SyntaxError: Expected a statement


42-42: SyntaxError: Simple statements must be separated by newlines or semicolons


42-42: SyntaxError: Expected ',', found ':'


42-42: SyntaxError: Expected ',', found name


42-42: SyntaxError: Expected ',', found name


42-42: SyntaxError: Expected ',', found name


42-42: SyntaxError: Expected ',', found name


42-42: SyntaxError: Expected ',', found name


44-44: SyntaxError: Unexpected indentation

🪛 Biome (1.9.4)
snapshots/countries/SG_COMMON.json

[error] 956-956: unexpected character <

(parse)


[error] 956-956: unexpected character <

(parse)


[error] 956-956: unexpected character <

(parse)


[error] 956-956: unexpected character <

(parse)


[error] 956-956: unexpected character <

(parse)


[error] 956-956: unexpected character <

(parse)


[error] 956-956: String values must be double quoted.

(parse)


[error] 957-957: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 957-957: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 957-957: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 957-958: unexpected character =

(parse)


[error] 958-958: unexpected character =

(parse)


[error] 958-958: unexpected character =

(parse)


[error] 958-958: unexpected character =

(parse)


[error] 958-958: unexpected character =

(parse)


[error] 958-958: unexpected character =

(parse)


[error] 958-958: unexpected character =

(parse)


[error] 958-959: unexpected character >

(parse)


[error] 959-959: unexpected character >

(parse)


[error] 959-959: unexpected character >

(parse)


[error] 959-959: unexpected character >

(parse)


[error] 959-959: unexpected character >

(parse)


[error] 959-959: unexpected character >

(parse)


[error] 959-959: unexpected character >

(parse)


[error] 959-959: Missing exponent

Expected a digit as the exponent

(parse)


[error] 959-959: unexpected character (

(parse)

🪛 actionlint (1.7.4)
.github/workflows/ci-cd.yml

61-61: could not parse as YAML: yaml: line 61: could not find expected ':'

(syntax-check)

🪛 YAMLlint (1.35.1)
.github/workflows/ci-cd.yml

[error] 62-62: syntax error: could not find expected ':'

(syntax)

🔇 Additional comments (18)
AUTHORS.md (1)

22-22: Author entry correctly added.

The new author "Ary Hauffe Neto" has been properly added in alphabetical order.

holidays/calendars/hindu.py (1)

1196-1200: Yet another conflict block – THAIPUSAM dates

Same story – the file will never import until all markers are removed. Please sweep the whole module (git grep '<<<<<<<') before pushing.

🧰 Tools
🪛 Ruff (0.8.2)

1196-1196: SyntaxError: Expected ',', found '<<'


1196-1196: SyntaxError: Expected ',', found '<<'


1196-1196: SyntaxError: Expected ',', found '<<'


1196-1196: SyntaxError: Expected ',', found '<'


1197-1197: SyntaxError: Expected ':', found int


1197-1197: SyntaxError: Expected ',', found ':'


1197-1197: SyntaxError: Expected ':', found ','


1198-1198: SyntaxError: Expected ',', found '=='


1198-1198: SyntaxError: Expected ',', found '=='


1198-1198: SyntaxError: Expected ',', found '=='


1198-1198: SyntaxError: Expected ',', found '='


1199-1199: SyntaxError: Expected ',', found '>>'


1199-1199: SyntaxError: Expected ',', found '>>'


1199-1199: SyntaxError: Expected ',', found '>>'


1199-1199: SyntaxError: Expected ',', found '>'


1199-1199: SyntaxError: Expected ':', found name


1199-1199: SyntaxError: Expected ',', found ':'


1199-1199: SyntaxError: Expected ',', found name


1199-1199: SyntaxError: Expected ',', found name


1199-1199: SyntaxError: Expected ',', found name


1199-1199: SyntaxError: Expected ',', found name


1199-1199: SyntaxError: Expected ',', found name

holidays/countries/ethiopia.py (1)

55-62: Return-type annotation accidentally removed

Guidance from previous PRs says only _is_leap_year in this file should carry a return annotation to match holiday_base.py. After conflict resolution the annotation disappeared. Restore it:

-    def _is_leap_year(self):
+    def _is_leap_year(self) -> bool:

[ suggest_nitpick ]

🧰 Tools
🪛 Ruff (0.8.2)

55-56: SyntaxError: Expected an indented block after function definition


56-56: SyntaxError: Expected a statement


56-56: SyntaxError: Expected a statement


56-56: SyntaxError: Expected a statement


56-56: SyntaxError: Expected a statement


56-57: SyntaxError: Expected a statement


57-57: SyntaxError: Unexpected indentation


60-61: SyntaxError: Expected an indented block after function definition


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Expected a statement


61-61: SyntaxError: Simple statements must be separated by newlines or semicolons


61-61: SyntaxError: Expected ',', found ':'


61-61: SyntaxError: Expected ',', found name


61-61: SyntaxError: Expected ',', found name


61-61: SyntaxError: Expected ',', found name


61-61: SyntaxError: Expected ',', found name


61-61: SyntaxError: Expected ',', found name


62-62: SyntaxError: Unexpected indentation

SECURITY.md (1)

7-8: Looks good - security policy version update

The version update in the security policy aligns properly with the project's version update strategy.

README.md (3)

151-156: LGTM! Åland Islands entry correctly added.

The Åland Islands entry is properly added to the README with the correct default language (sv_FI), supported languages, and category (UNOFFICIAL). It correctly indicates that it can be loaded as country FI, subdivision 01.


524-524: LGTM! Finland subdivision entry is correctly updated.

The Finland entry now properly lists Åland as its subdivision with the correct subdivision code (01) and proper naming in multiple languages.


511-512: LGTM! Ethiopia entry is correctly updated.

The Ethiopia entry has been updated to remove the "en_ET" language and the "WORKDAY" category as required.

tests/countries/test_finland.py (4)

392-392: LGTM: Åland's Autonomy Day added to default localization test

The holiday has been correctly added to the localization test for 2022.


432-432: LGTM: English localized name for Åland's Autonomy Day

The English (US) localized holiday name "Åland's Autonomy Day" has been correctly added to the test.


472-472: LGTM: Ukrainian localized name for Åland's Autonomy Day

The Ukrainian localized holiday name "День автономії Аландських островів" has been correctly added to the test.


512-512: LGTM: Swedish localized name for Åland's Autonomy Day

The Swedish (Finland) localized holiday name "Ålands självstyrelsedag" has been correctly added to the test.

scripts/calendar/asian_generator.py (1)

287-292: Update lunar calendar year range and dates

The supported year range has been changed from 1901-2100 to 1901-2099, with corresponding updates to the end dates. This change is consistent with the updated hex values in G_LUNAR_MONTH_DAYS.

The change improves the accuracy of lunar calendar calculations by restricting to a verified range.

holidays/groups/chinese.py (1)

36-37: LGTM: Simplified Chinese calendar initialization

The removal of the calendar parameter simplifies the instantiation of the Chinese calendar object. This change aligns with updates to the Chinese calendar implementation that no longer requires a calendar parameter.

🧰 Tools
🪛 Ruff (0.8.2)

36-36: SyntaxError: Unexpected indentation

holidays/countries/south_korea.py (1)

302-327: The new implementation improves extensibility and accuracy.

The new SouthKoreaLunisolarHolidays class provides a more maintainable approach to handling country-specific lunar calendar holidays. By defining specific dates for key years, it ensures accurate holiday calculations while still inheriting general behavior from _CustomChineseHolidays.

This implementation makes it easier to adjust specific holiday dates for South Korea without modifying the core lunisolar calendar logic. The dictionaries for Buddha's Birthday, Lunar New Year, and Mid-Autumn Festival provide a clean way to specify exceptions or fixed dates for specific years.

snapshots/countries/ET_COMMON.json (2)

343-363: Standardized holiday names improve consistency.

The incoming changes standardize holiday names (e.g., "Epiphany" → "Epiphany Day", "International Workers' Day" → "Workers' Day"). This aligns with the simplified naming convention in the localization files.

Ensure these standardized names match the message IDs used in the localization files to maintain consistency throughout the codebase.


2038-2085: The extended holiday dataset improves coverage.

The incoming change provides holiday data through 2050, which significantly improves the coverage and usefulness of the Ethiopian holiday calendar. This expansion is valuable for long-term planning and historical analysis.

The addition of estimated dates for Islamic holidays (Eid al-Fitr, Eid al-Adha, Prophet's Birthday) with consistent naming across the entire date range makes the dataset more complete and usable.

tests/countries/test_aland_islands.py (1)

38-42: Duplicate & conflicting assertions – pick one range check

The two branches disagree on the years where Autonomy Day is absent:

self.assertNoHolidayName(name, range(1921, 1993))
# vs
self.assertNoHolidayName(name, range(1853, 1993))

Unless you have evidence of Autonomy-Day observations before 1921, prefer the shorter range (1921 is when Finland started flag days). Whichever is correct, keep one and delete the other when you fix the conflict.

🧰 Tools
🪛 Ruff (0.8.2)

38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


38-38: SyntaxError: Expected a statement


39-39: SyntaxError: Unexpected indentation


40-40: SyntaxError: Expected a statement


40-40: SyntaxError: Expected a statement


40-40: SyntaxError: Expected a statement


40-40: SyntaxError: Expected a statement


40-41: SyntaxError: Expected a statement


41-41: SyntaxError: Unexpected indentation


42-42: SyntaxError: Expected a statement


42-42: SyntaxError: Expected a statement


42-42: SyntaxError: Expected a statement


42-42: SyntaxError: Expected a statement


42-42: SyntaxError: Simple statements must be separated by newlines or semicolons


42-42: SyntaxError: Expected ',', found ':'


42-42: SyntaxError: Expected ',', found name


42-42: SyntaxError: Expected ',', found name


42-42: SyntaxError: Expected ',', found name


42-42: SyntaxError: Expected ',', found name


42-42: SyntaxError: Expected ',', found name

tests/countries/test_ethiopia.py (1)

150-214: Inconsistent holiday names after refactor

The slimmed-down branch shortens names (e.g. "አድዋ" vs "የአድዋ ድል በዓል"). Ensure the names tested here match the canonical names returned by holidays.countries.ethiopia.Ethiopia after the code changes. Out-of-sync strings will give false negatives.

🧰 Tools
🪛 Ruff (0.8.2)

155-155: SyntaxError: unindent does not match any outer indentation level


160-160: SyntaxError: unindent does not match any outer indentation level


164-164: SyntaxError: Expected ',', found '=='


164-164: SyntaxError: Expected ',', found '=='


164-164: SyntaxError: Expected ',', found '=='


164-164: SyntaxError: Expected ',', found '='


168-168: SyntaxError: unindent does not match any outer indentation level


171-171: SyntaxError: unindent does not match any outer indentation level


176-176: SyntaxError: unindent does not match any outer indentation level


181-181: SyntaxError: unindent does not match any outer indentation level


190-190: SyntaxError: unindent does not match any outer indentation level


199-199: SyntaxError: unindent does not match any outer indentation level


209-209: SyntaxError: unindent does not match any outer indentation level


214-214: SyntaxError: unindent does not match any outer indentation level

@Arynelson
Copy link
Contributor Author

@Arynelson, you have other branch aland-island in your repo, that is more up-to-date than this one - Aland-Island. Isn't this some kind of typo?

You are right @KJhellico i made a mistake with typo , i try to fix this now . If i do everything as i espect the Aland-Island be up-to-date now .

@PPsyrius
Copy link
Collaborator

PPsyrius commented Apr 25, 2025

@Arynelson I've fixed up merge errors for you in Arynelson#3, alongside other changes which also includes:

  • Increments country count and version number to 171, 0.72 respectively.
  • AUTHORS.md -> CONTRIBUTORS.md migration.
  • Remove our temp workaround for generate_po_files.py, now that this works properly with the new Lingva update.
  • Fix Finnish May Day trigger, general Finnish test case refactoring to meet the new library-wide standard.

image

@arkid15r
Copy link
Collaborator

@Arynelson do you plan to finish your work or we can close it?

@KJhellico
Copy link
Collaborator

I think we have to finish this PR, there is not much left to do. @PPsyrius, I think you should push your changes directly to the original branch, or create your own PR and we'll finish it there.

@PPsyrius
Copy link
Collaborator

PPsyrius commented May 9, 2025

Superceded by #2537 🙏

@PPsyrius PPsyrius closed this May 9, 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 Åland Islands holidays

4 participants