Skip to content

Add Macau holidays#2323

Merged
arkid15r merged 21 commits into
vacanza:devfrom
PPsyrius:macau
Mar 8, 2025
Merged

Add Macau holidays#2323
arkid15r merged 21 commits into
vacanza:devfrom
PPsyrius:macau

Conversation

@PPsyrius

@PPsyrius PPsyrius commented Mar 3, 2025

Copy link
Copy Markdown
Collaborator

Proposed change

Add Macau holidays.

  • Adds Supported categories: MANDATORY (1985-Present), GOVERNMENT (2005-Present), and PUBLIC (1982-Present).
  • Adds Historical Subdivisions holidays: Concelho das Ilhas, Concelho de Macau.
  • Adds Supported l10ns: Macanese English (en_MO), American English (en_US), Macanese Portuguese (pt_MO), Thai (th), Simplified Chinese (zh_CN), Macanese Traditional Chinese (zh_MO).
  • Adds/Refractors ChineseCalendarGroup raw date data methods.

Resolves #2269 .

Note

Due to l10n limitations regarding grammars and prepositions, Portuguese translation for Compensatory Rest Days may not 100% match official Macanese government sources i.e. a/o/ao.

Type of change

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

Checklist

@coderabbitai

coderabbitai Bot commented Mar 3, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added full support for Macau holidays, including public, mandatory, and government observances with extended calendar data (1982–2050).
  • Documentation
    • Updated the supported country list (now 160 countries) to include Macau.
    • Introduced new localizations for Macau holidays in multiple languages (en_MO, en_US, pt_MO, th, zh_CN, zh_MO).

Walkthrough

The changes expand support for Macau holidays throughout the library. The README has been updated to include a new entry for Macau, and supporting constants, classes, and registry updates have been introduced. Additionally, variable names and methods in the Hong Kong and Chinese holiday modules have been refined for clarity. New localization files and snapshot JSON files provide comprehensive holiday data for Macau, while an extensive test suite has been implemented to validate the holiday logic.

Changes

File(s) Change Summary
README.rst, holidays/constants.py, holidays/countries/__init__.py, holidays/countries/macau.py, holidays/registry.py Expanded Macau holiday support: updated README with a new Macau entry, added constant MANDATORY, imported the Macau module, introduced new Macau holiday classes, and updated the country registry.
holidays/countries/hongkong.py, holidays/groups/chinese.py Renamed variables and updated methods in holiday calculations (e.g., _qingming_date_qingming_festival), and added new methods for Chinese holiday determination.
holidays/locale/{en_MO,en_US,pt_MO,th,zh_CN,zh_MO}/LC_MESSAGES/MO.po Added new localization files for Macau holidays in multiple languages.
snapshots/countries/{MO_COMMON,MO_I,MO_M}.json Created snapshot JSON files containing comprehensive Macau holiday data from 1982 to 2050.
tests/countries/test_macau.py Introduced a new test suite for validating Macau holiday logic.

Possibly related PRs

Suggested reviewers

  • KJhellico

📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 06e0a30 and 3b0366e.

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

215-215: Method call update enhances consistency with Chinese calendar handling

The change from using the _winter_solstice_date property to calling _add_dongzhi_festival method improves code organization by standardizing how Chinese calendar holidays are handled. The term "Dongzhi" is also culturally appropriate as the Chinese name for the Winter Solstice Festival.


238-238: Property naming improvement for cultural clarity

Renaming from _qingming_date to _qingming_festival provides better semantic clarity that this refers to the cultural festival rather than just a date calculation.


260-260: Improved code encapsulation for Buddha's birthday

The change from direct calendar access with explicit indexing (self._chinese_calendar.buddha_birthday_date(self._year)[0]) to using the encapsulated property self._chinese_birthday_of_buddha is a significant improvement in code maintainability and readability.


277-277: Better abstraction for Dragon Boat Festival date

Moving from explicit calendar method call to the property self._dragon_boat_festival improves code readability and maintains consistency with other similar holiday dates, making maintenance easier.


296-296: Consistent approach for Double Ninth Festival

Similar to other changes, using the property self._double_ninth_festival instead of direct calendar access creates a more consistent API across the codebase, which will be helpful when extending holiday support to Macau as mentioned in the PR objectives.

✨ Finishing Touches
  • 📝 Generate Docstrings

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

@KJhellico

Copy link
Copy Markdown
Collaborator

@PPsyrius , it's great! Eastern countries, as usual, are not so simple... I understand you haven't finished this yet?

@PPsyrius

PPsyrius commented Mar 3, 2025

Copy link
Copy Markdown
Collaborator Author

@KJhellico I'm not satisfied with the current in-lieu setup for National Day-Cheung Yeung-Chong Chao yet considering its hacky implementation - but it's more or less working, yes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (2)
snapshots/countries/MO_I.json (1)

1-1720: 🧹 Nitpick (assertive)

Overall JSON Structure and Content Review

The snapshot file is very comprehensive and appears to be a valid JSON document. All keys (date strings in ISO format) and corresponding holiday descriptions are properly quoted and separated by commas. The file spans a long period (1982–2050), which looks impressive and should cover the necessary range for Macau holiday support.

A couple of points to consider:

  • Some entries combine multiple holiday descriptions using semicolons (e.g., "1985-04-05": "Ching Ming Festival; Good Friday"). Please double-check that this format is intentional and aligns with official holiday data.
  • For long-term maintainability, you might consider adding a brief header or metadata section (even as a comment before the JSON begins) describing the source of the data and the last update timestamp.

Overall, the file meets its purpose and the structure is solid.

holidays/locale/zh_MO/LC_MESSAGES/MO.po (1)

232-235: 💡 Verification agent

🧩 Analysis chain

Duplicate entry for Mid-Autumn Festival.

The entry for "中秋節" (Chong Chao/Mid-Autumn Festival) appears twice in the file - once at lines 153-156 and again here.


🏁 Script executed:

#!/bin/bash
# Check if there are other duplicated holiday entries in the zh_MO locale file
grep -A 1 "msgid" holidays/locale/zh_MO/LC_MESSAGES/MO.po | grep -v "^--$" | grep -v "#" | sort | uniq -d

Length of output: 115


Heads up: Duplicate Mid-Autumn Festival Entry

It appears that the "中秋節" entry is defined twice in the file (once at lines 153–156 and again at lines 232–235). The verification script confirmed a duplicate by showing the repeated empty translation line (msgstr ""). Please remove one of the entries to ensure there’s only a single, unique definition.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3f52858 and 71993f3.

📒 Files selected for processing (17)
  • README.rst (2 hunks)
  • holidays/constants.py (1 hunks)
  • holidays/countries/__init__.py (1 hunks)
  • holidays/countries/hongkong.py (4 hunks)
  • holidays/countries/macau.py (1 hunks)
  • holidays/groups/chinese.py (4 hunks)
  • holidays/locale/en_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/pt_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/zh_CN/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/zh_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/registry.py (1 hunks)
  • snapshots/countries/MO_COMMON.json (1 hunks)
  • snapshots/countries/MO_I.json (1 hunks)
  • snapshots/countries/MO_M.json (1 hunks)
  • tests/countries/test_macau.py (1 hunks)
🔇 Additional comments (43)
holidays/constants.py (1)

45-45: Clean addition of new holiday category.

The new MANDATORY constant is properly placed in alphabetical order among other holiday categories and follows the naming convention of the codebase.

holidays/countries/__init__.py (1)

103-103: Import statement follows established pattern.

The Macau import statement is correctly placed in alphabetical order and follows the same structure as other country imports with proper country name and ISO codes.

holidays/registry.py (1)

111-111: Proper registry entry for Macau.

The Macau entry in the COUNTRIES dictionary follows the correct format with the key "macau" mapped to a tuple containing the display name "Macau" and the ISO codes "MO" (alpha-2) and "MAC" (alpha-3).

holidays/locale/zh_CN/LC_MESSAGES/MO.po (3)

1-29: File header follows standard format.

The localization file header contains all required metadata including project version, creation date, translator information and proper charset settings.


30-235: Comprehensive holiday translations from Traditional to Simplified Chinese.

The file provides thorough translations for all Macau holidays, including:

  • Traditional Chinese festivals (Lunar New Year, Mid-Autumn Festival)
  • Portuguese heritage holidays (Day of Portugal, Republic Day)
  • Religious observances (Christmas, All Saints' Day)
  • Civic holidays (Macau SAR Establishment Day)
  • Supporting format strings for compound holiday names

All translations correctly convert Traditional Chinese characters to their Simplified Chinese equivalents.


233-234: Check character translation for "重疊".

In line 234, "重疊" is translated to "重迭" in Simplified Chinese. While both are valid, the more common simplified form is "重叠". You might want to verify this translation with a native speaker.

snapshots/countries/MO_M.json (1)

1-1718: General Review for JSON Holiday Data File

This new JSON file provides a comprehensive list of Macau holiday data spanning 1982–2050. The keys (dates) are formatted consistently in "YYYY-MM-DD" style, and the holiday names appear well organized. Please ensure that any Unicode characters (for example, in names with Chinese characters) are rendered correctly across different environments or when parsed by the application.

README.rst (2)

155-164: Supported Country Codes Update

The README now correctly states that 160 country codes are supported, which aligns nicely with the inclusion of Macau. Just double-check that this update is reflected in all relevant documentation sections.


629-634: New Macau Entry in Supported Countries Table

The added entry for Macau is clear and consistent. It specifies the country code "MO", details historical municipalities, provides a list of supported languages (including en_MO, en_US, pt_MO, th, zh_CN, and zh_MO), and correctly lists the supported holiday categories (“GOVERNMENT” and “MANDATORY”). This fits well with the overall table format.

holidays/locale/th/LC_MESSAGES/MO.po (1)

1-1718: New Thai Localization File for Macau Holidays

The new PO file is structured in accordance with standard gettext practices. The header metadata (project version, creation and revision dates, translator info, etc.) looks accurate, and each msgid-msgstr pair is clearly defined with appropriate translations. Please verify that some of the more culturally nuanced translations (for instance, those covering the complex descriptions for events like Macau’s Handover) reflect the local usage accurately.

snapshots/countries/MO_COMMON.json (1)

1-1701: Well-structured holiday data with comprehensive coverage.

The file provides an extensive and systematic compilation of Macau holidays spanning from 1982 to 2050. Good chronological organization and proper JSON formatting.

holidays/locale/pt_MO/LC_MESSAGES/MO.po (3)

17-27: Appropriate metadata structure for localization file.

The metadata section contains all necessary information including version, date, and translator details.


30-245: Complete Portuguese translations for all Macau holidays.

Comprehensive set of translations covering all holiday types, including traditional, religious, and government holidays specific to Macau.


207-210: Proper handling of variable substitution in compensatory rest days.

The translation correctly uses the %s placeholder for the variable holiday name in compensatory rest day descriptions.

holidays/locale/en_US/LC_MESSAGES/MO.po (3)

17-27: Standard localization metadata properly configured.

The file contains comprehensive metadata with appropriate project information and language settings.


184-188: Clear handling of multi-line holiday name translations.

Long holiday names are properly formatted across multiple lines while maintaining readability.


215-218: Effective pattern for afternoon designations.

Simple and effective pattern for handling time-specific holidays using the %s placeholder.

holidays/locale/zh_MO/LC_MESSAGES/MO.po (2)

17-27: Standard metadata format for Traditional Chinese locale.

Proper header information with appropriate zh_MO language designation.


29-209: Intentionally empty msgstr fields for native language entries.

The empty msgstr fields are appropriate since the msgid values already contain the correct Traditional Chinese holiday names for Macau.

holidays/locale/en_MO/LC_MESSAGES/MO.po (2)

85-96: Observe the triple mapping for Christmas Eve.

Lines 85-96 define three distinct msgid values all mapped to "Christmas Eve." While this is intentional for different historical forms, verify each variant is genuinely needed to avoid confusion.


29-243: All translations appear consistent and valid.

No syntax or grammar concerns found. The file is in a good state.

holidays/groups/chinese.py (3)

38-45: Check the conditional for Qingming calculations.

Lines 43-44 reference self._year % 4 < 1 or self._year % 4 < 2 with an additional and self._year >= 2009. Confirm the logic covers all required edge cases and offsets for Qingming accurately.


54-75: Fully documented new properties.

The newly introduced properties _chinese_birthday_of_buddha, _dragon_boat_festival, and _double_ninth_festival align well with the naming convention and seem correct.


156-164: Nice addition of the fifth day of Lunar New Year.

The _add_chinese_new_years_day_five method extends coverage for the holiday. Implementation looks consistent with the existing pattern.

holidays/countries/macau.py (3)

613-624: The winter solstice approximation is clear.

This approach is straightforward for the defined year range. Confirm external references or future expansions won't break the approximation beyond 2099.


627-633: Subdivision classes appear fine.

Classes MO and MAC are simple aliases with no additional logic. Implementation is acceptable.


635-690: StaticHolidays definitions look complete.

The reference dictionaries, special holidays, and text translations are coherent.

tests/countries/test_macau.py (12)

1-12: Well structured file header with correct licensing information

The header contains proper attribution and licensing information, maintaining consistency with the rest of the codebase.


13-18: Proper imports with clear dependency relationships

The imports are well organized, importing only what's needed and clearly showing the dependencies for the test class. Good practice to import TestCase and CommonCountryTests which provides reusable test functionality.


20-26: Good test class setup with appropriate inheritance and year ranges

The test class properly inherits from both CommonCountryTests and TestCase. The setUpClass method establishes a good test range (1981-2050) and correctly initializes different holiday category instances for testing.


27-32: Basic functionality tests are comprehensive

Tests for country aliases and no-holiday conditions are well implemented. Good job verifying both the positive cases (aliases work) and negative cases (no holidays for years when categories didn't exist).


34-64: Well-documented special holiday tests with reliable sources

The special holiday tests are thorough and include source URLs for verification. Good organization of test data into separate tuples for full-day, half-day, and government holidays.


66-91: Comprehensive New Year's Day test coverage across categories

Tests properly verify New Year's Day for different categories (government, mandatory, public) and include compensatory holiday cases. Good use of date ranges and specific date checks.


92-98: Historical holiday verification for Freedom Day

Good inclusion of historical holiday testing (Freedom Day) with verification that it stopped being a holiday after 1999.


674-679: Proper implementation of subdivision-specific holidays

The tests for municipality-specific holidays are well implemented, using the subdiv parameter to test holidays that only apply to specific areas of Macau.


681-696: Direct verification against official mandatory holiday list

Excellent verification against the official mandatory holiday list for 2024 with source reference in the comment. This provides an important validation point against official records.


697-928: Comprehensive year-by-year holiday verification

The thorough testing of holidays for each year from 2017-2025 against official sources creates a robust verification process. The explicit date and name checks will catch any regression issues.


930-1098: Excellent localization testing coverage

The localization tests verify holiday names in multiple languages (default, en_MO, en_US, pt_MO, zh_CN). This is critical for ensuring correct localized display of holidays.


294-380: Thorough Lunar New Year tests with complex logic coverage

The Lunar New Year tests are very detailed and cover various edge cases including compensation days. Good attention to detail with specific date verification across a range of years.

holidays/countries/hongkong.py (4)

238-238: Good variable rename for better code clarity

Changing from self._qingming_date to self._qingming_festival improves name consistency with other festival properties and makes the code more readable.


260-260: Improved abstraction by using property instead of direct method call

Replacing the verbose self._chinese_calendar.buddha_birthday_date(self._year)[0] with the cleaner self._chinese_birthday_of_buddha property enhances code maintainability and readability.


277-277: Consistent naming pattern for festival date properties

The change to self._dragon_boat_festival maintains consistency with the naming pattern used for other festival dates in the codebase.


296-296: Better abstraction of calendar calculation logic

Changing to self._double_ninth_festival moves the calendar calculation details away from this class, making the code cleaner while maintaining the same functionality.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (2)
holidays/locale/zh_MO/LC_MESSAGES/MO.po (1)

233-236: 🧹 Nitpick (assertive)

Possible duplicate entry for Mid-Autumn Festival.

There appears to be a duplicate entry for "Chong Chao (Mid-Autumn) Festival" at line 233-235, which was already defined at lines 154-157. Consider removing one of these entries to avoid confusion.

-#. Chong Chao (Mid-Autumn) Festival.
-msgid "中秋節"
-msgstr ""
holidays/locale/en_MO/LC_MESSAGES/MO.po (1)

1-244: 🧹 Nitpick (assertive)

Consolidate duplicate holiday strings if desired.

All translations appear consistent and correct. If you'd prefer a single English mapping for the three Chinese variations of Christmas Eve or unify any other subtly different strings (e.g., "Christmas Eve" vs "Christmas Eve"), please feel free to consolidate them. This is purely optional and would not affect functionality.

♻️ Duplicate comments (2)
holidays/countries/macau.py (2)

84-98: 🧹 Nitpick (assertive)

Rename _add_observed_two_day for clarity.

This method handles overlapping or consecutive compensatory holidays. A more descriptive name, such as _add_observed_two_day_overlap, may help future maintainers.


285-595: 🛠️ Refactor suggestion

Large branching structure in _populate_government_holidays.

This method handles numerous if-else clauses for date overlaps. Extracting dedicated helper functions or adopting a more data-driven approach would reduce complexity and enhance readability.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 71993f3 and 02c0a16.

📒 Files selected for processing (11)
  • holidays/countries/macau.py (1 hunks)
  • holidays/locale/en_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/pt_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/zh_CN/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/zh_MO/LC_MESSAGES/MO.po (1 hunks)
  • snapshots/countries/MO_COMMON.json (1 hunks)
  • snapshots/countries/MO_I.json (1 hunks)
  • snapshots/countries/MO_M.json (1 hunks)
  • tests/countries/test_macau.py (1 hunks)
🔇 Additional comments (39)
holidays/locale/zh_CN/LC_MESSAGES/MO.po (8)

1-27: Header information looks good.

File header contains all necessary metadata for proper localization handling.


30-31: Simplified Chinese translation for New Year's Day is accurate.

Translation maintains the same meaning while properly converting to simplified characters.


37-39: Labor Day translation is correctly simplified.

The translation "劳动节" is the proper simplified Chinese version of "勞動節".


89-95: Multiple Christmas Eve translations handled properly.

The file correctly provides translations for the three different source texts for Christmas Eve.


149-152: Appropriate handling of multiple comments for the same source text.

The file correctly handles multiple comments for "重陽節" (Chung Yeung Festival).


182-186: Complete translation for complex holiday names.

The translation properly handles the long holiday name "The Handover of Macau to China and the Establishment of the Macau Special Administrative Region of the People's Republic of China".


203-206: Format string translation is correctly implemented.

The placeholder %s is properly maintained in the translation, allowing for dynamic holiday names in the compensatory rest day format.


231-235: Translation choice for 'Overlapping' term.

The term "重迭" (chóngdié) is used for "重疊" (chóngdié), which is an appropriate simplified Chinese equivalent for the concept of overlapping holidays.

snapshots/countries/MO_M.json (9)

1-24: Initial holidays for 1982 correctly formatted.

The JSON structure follows the expected date-string key with holiday name value format. The coverage begins with 1982, which matches the PR objective to provide holiday support from 1982 onwards.


80-80: Proper handling of multiple holidays on same date.

April 5, 1985 correctly lists both "Ching Ming Festival" and "Good Friday" when they occurred on the same day.


276-278: Multiple holiday concatenation is properly handled.

Both entries correctly combine multiple holidays occurring on the same day using a semicolon separator.


398-402: Additional public holidays are correctly defined.

The file properly includes additional and half-day public holidays, such as those at the end of 1998.


424-425: Historical significance: Macau handover in 1999.

The file correctly captures the historical handover of Macau to China on December 20, 1999, and the following day.


683-685: Government holiday designation is properly included.

Additional government holidays are correctly designated, such as the one on October 3, 2012.


861-862: Compensatory rest days implementation is consistent.

The naming convention for compensatory rest days maintains consistency throughout the file, following the format "Compensatory rest day for [Holiday Name]".


872-873: Edge case handling for overlapping holidays.

The file correctly handles the edge case where two holidays (National Day following day and Mid-Autumn Festival following day) would overlap on October 2, 2020, with a special entry for October 5, 2020.


1702-1717: Future holiday projections extend to 2050.

The file provides holiday projections up to 2050, giving ample forward-looking data for applications.

holidays/locale/th/LC_MESSAGES/MO.po (8)

1-27: Thai localization header is properly formatted.

The metadata correctly specifies Thai as the target language with proper encoding settings.


30-31: New Year's Day translation is accurate.

"วันขึ้นปีใหม่" is the correct Thai term for New Year's Day.


49-51: National Day translation is appropriately simplified.

The translation uses the common Thai name "วันชาติจีน" (China National Day) rather than a literal translation of the longer Chinese name, which is appropriate for Thai usage.


81-83: Cultural context preserved in Winter Solstice translation.

The translation "วันตงจื้อ(เหมายัน)" includes both the transliterated Chinese term (Dong Zhi) and the Thai astronomical term (Mayhan) in parentheses, which is helpful for Thai readers.


137-139: Buddha's Birthday appropriately localized.

The translation correctly uses "วันวิสาขบูชา" (Visakha Bucha Day), which is the equivalent Thai Buddhist holiday.


182-187: Long holiday name properly translated.

The translation maintains all the key components of the long holiday name while ensuring it reads naturally in Thai.


203-206: Format string pattern preserved correctly.

The placeholder %s is properly maintained in the translation with the appropriate Thai grammar structure for "compensatory day for [holiday]".


234-239: Complex overlapping holiday explanation clearly translated.

The translation properly explains the concept of overlapping holidays in natural Thai phrasing.

snapshots/countries/MO_I.json (1)

1-1720: Extensive and Well-Structured Macau Holidays JSON File

The JSON file provides an impressively detailed list of Macau holidays spanning from 1982 to 2050. The entries are clear and consistently formatted, with each date string mapped to a descriptive holiday name. A few things to note:

  • Consistency & Accuracy:
    Please double-check that all holiday names (including compensatory rest days and any composite holidays) align with official data and the terminology used elsewhere in the project. This is especially important given the known limitations regarding Portuguese translations.

  • Data Sorting & Formatting:
    The dates appear to be in an appropriate ascending order, and the JSON format looks correct. Just ensure that any modules referencing this snapshot file expect a sorted structure or can handle the data as provided.

  • Integration with Holiday Calculations:
    Confirm that the holiday calculation logic in the macau.py module (or its equivalent) correctly utilizes this extensive data set, particularly handling overlaps or special cases noted by the contributor.

Overall, great work on covering a wide range of dates and holiday variants. This file should serve as a robust foundation for Macau holiday support.

snapshots/countries/MO_COMMON.json (1)

1-1701: Well structured holiday data. Good job.

This JSON file contains comprehensive holiday data for Macau from 1982 to 2050, properly formatted with dates as keys and holiday names as values. The inclusion of various holiday types (traditional, cultural, and commemorative) along with compensatory rest days shows thorough attention to detail.

holidays/locale/pt_MO/LC_MESSAGES/MO.po (4)

15-28: Metadata looks good.

The PO file metadata includes all necessary information: project version, creation/revision dates, translator details, and proper character encoding.


29-106: Common holiday translations are accurate.

The Portuguese translations for common holidays like New Year's Day ("Fraternidade Universal"), Labor Day ("Dia do Trabalhador"), and Christmas ("Natal") are correct.


107-163: Cultural festival translations look good.

The Portuguese translations for cultural festivals like Lunar New Year ("Novo Ano Lunar"), Ching Ming ("Cheng Ming"), and Chong Chao ("Bolo Lunar") preserve cultural meaning while making them accessible to Portuguese speakers.


207-212: Format string for compensatory days is proper.

The translation for compensatory rest days follows the correct format string pattern that will properly interpolate holiday names at runtime.

holidays/locale/en_US/LC_MESSAGES/MO.po (3)

15-28: Metadata follows standard format.

The English localization file has consistent metadata with the other locale files, maintaining uniformity across the project.


182-196: Lengthy holiday names are properly handled.

The translation for "The Handover of Macau to China..." maintains clarity despite being lengthy, using proper string continuation format.


237-244: Complex overlap case handled well.

The translation for the overlapping holiday situation (National Day and Mid-Autumn Festival) is clear and follows the same formatting pattern as other entries.

holidays/locale/zh_MO/LC_MESSAGES/MO.po (2)

15-28: Metadata consistent with other locale files.

The zh_MO locale file metadata maintains the same format and information as the other localization files, showing good consistency.


29-236: Empty message strings are appropriate for native language.

The empty message strings (msgstr) are correct for this file since the original message IDs (msgid) are already in Chinese. This is standard practice when the source and target languages match.

tests/countries/test_macau.py (2)

20-26: Solid setup for comprehensive testing.

Initializing multiple holiday sets for different categories and years ensures excellent coverage from 1981 through 2050.


34-65: Good approach for verifying special holidays.

You have identified large date spans for thorough testing of special and half-day holidays. This ensures accurate coverage of sporadic events. Great job!

holidays/countries/macau.py (1)

45-45:

Details

✅ Verification successful

Verify external law reference link.

The reference to Lei n.º 27/2024 on line 45 may be future legislation. Please ensure that this link is valid and the year is correct.


🏁 Script executed:

#!/bin/bash
# Checking if the referenced public URL is reachable (HTTP status).
curl -I https://bo.io.gov.mo/bo/i/2025/01/lei27.asp

Length of output: 1515


External law reference link verified – no issues found

The link for Lei n.º 27/2024 (pointing to https://bo.io.gov.mo/bo/i/2025/01/lei27.asp#an2l63) returns an HTTP 200 OK, so it appears to be valid. Although the law is cited as "27/2024" while the URL is under the 2025 directory, the release pattern on the official site can explain this discrepancy. Please confirm with the official legislative documentation if the year notation is correct; otherwise, no changes are required.

Comment thread tests/countries/test_macau.py
@PPsyrius PPsyrius marked this pull request as ready for review March 4, 2025 09:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 02c0a16 and 4866b5d.

📒 Files selected for processing (11)
  • holidays/countries/macau.py (1 hunks)
  • holidays/locale/en_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/pt_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/zh_CN/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/zh_MO/LC_MESSAGES/MO.po (1 hunks)
  • snapshots/countries/MO_COMMON.json (1 hunks)
  • snapshots/countries/MO_I.json (1 hunks)
  • snapshots/countries/MO_M.json (1 hunks)
  • tests/countries/test_macau.py (1 hunks)
🔇 Additional comments (23)
snapshots/countries/MO_M.json (1)

1-1721: Well-structured and comprehensive holiday data for Macau.

This JSON file provides an extensive collection of Macau holidays from 1982 to 2050, covering all required categories mentioned in the PR description: MANDATORY (1985-Present), GOVERNMENT (1982-Present), and PUBLIC (1982-Present). The data includes traditional Chinese holidays, Portuguese colonial holidays, and post-handover holidays, showing a clear historical timeline.

The data is consistently formatted and appears accurate with proper attention to:

  • Historical shifts in holiday observances (pre and post-handover in 1999)
  • Compensatory rest days for weekend holidays
  • Special cases where holidays overlap
  • Half-day holidays
holidays/locale/th/LC_MESSAGES/MO.po (2)

17-27: Project metadata is correctly configured for Thai localization.

The header information properly identifies this as Thai localization for version 0.69 of the Holidays project. The charset is UTF-8 as needed for Thai characters.


29-239: Thai translations are accurate and comprehensive.

The translations cover all necessary Macau holidays including:

  • Standard civic holidays (New Year's, Labor Day)
  • Chinese traditional holidays (Lunar New Year, Mid-Autumn Festival)
  • Portuguese/Catholic observances (Christmas, Good Friday)
  • Local Macau-specific holidays

I particularly appreciate the accurate translation of complex holiday concepts like "The Handover of Macau to China" and the handling of formatted strings for compensatory rest days.

snapshots/countries/MO_I.json (1)

1-1722: Well-structured and comprehensive holiday data for Macau.

This file provides an extensive collection of Macau holidays from 1982 to 2050, including traditional Chinese festivals, Western holidays, and local observances. The JSON structure is clean and follows a consistent date-to-description mapping format.

The implementation thoroughly covers:

  • Lunar calendar holidays (New Year, Mid-Autumn, Dragon Boat Festival)
  • Western holidays (Christmas, Easter)
  • Local political holidays (Macao S.A.R. Establishment Day)
  • Compensatory rest days (for when holidays fall on weekends)

This comprehensive approach ensures the library properly reflects Macau's unique holiday calendar, which includes both Chinese and Portuguese influences.

holidays/locale/zh_CN/LC_MESSAGES/MO.po (7)

15-28: PO file metadata is correctly configured.

The metadata header contains all necessary fields for a properly functioning localization file including project version, creation date, language team information, and character encoding.


29-104: Core holiday translations look good.

The translations properly convert Traditional Chinese characters to Simplified Chinese for common holidays like New Year's Day, Labor Day and Christmas.


105-168: Cultural festival translations are accurate.

All traditional Chinese festivals and local Macau holidays have been properly translated from Traditional to Simplified Chinese characters.


169-180: Government holiday terminology translated correctly.

Additional government and public holiday terminology is properly formatted.


181-198: Special commemorative event translations are accurate.

The lengthy names for special events like the Handover of Macau and the 70th Anniversary of WWII Victory have been correctly translated while preserving their official formal naming.


199-212: Format string patterns maintain proper placeholder positioning.

The C-style format strings (using %s) are correctly structured in both Traditional and Simplified Chinese versions, ensuring proper runtime substitution of holiday names in generated text.


213-235: Additional holiday-specific translations are properly formatted.

The remaining holiday translations and special case for overlapping holidays are well-formed.

snapshots/countries/MO_COMMON.json (1)

1-1704: Thorough comprehensive coverage of Macau holidays.

The file provides an extensive holiday dataset for Macau from 1982 to 2050, covering all standard holidays, cultural observances, compensatory rest days, and special events.

holidays/locale/pt_MO/LC_MESSAGES/MO.po (3)

13-27: Translation metadata looks good.

All required metadata fields are present with appropriate values for the Macanese Portuguese locale.


77-81: Long translation handled well across multiple lines.

The multi-line translation for "Macao S.A.R. Establishment Day" follows PO file formatting best practices.


207-210:

Details

❓ Verification inconclusive

Verify this translation format for compensatory rest days.

The compensatory rest day format in Portuguese adds "relativo ao" which might create concatenation issues if the holiday name already includes prepositions.


🏁 Script executed:

#!/bin/bash
# Description: Check how this format string is used in code and if it handles grammar correctly

# Find where compensatory rest days are processed
rg -A 3 "補假" holidays/countries/macau.py

Length of output: 211


Action Required: Verify the Translation Format for Compensatory Rest Days

It looks like in holidays/locale/pt_MO/LC_MESSAGES/MO.po, the format string for compensatory rest days is defined as:

#. Compensatory rest day for %s.
#, c-format
msgid "%s的補假"
msgstr "Dia de descanso compensatório relativo ao %s"

In the code (see holidays/countries/macau.py), this string is used via self.tr("%s的補假"). Please double-check that injecting the holiday name into the %s placeholder doesn’t produce concatenation or grammar issues—particularly if the holiday name already includes prepositions or articles. Confirm that the resulting phrasing is natural for all holiday names.

  • Verify there are no unintended concatenation issues when substituting the holiday name.
  • Ensure that the structure “relativo ao %s” works correctly with the various holiday names that might be passed.
holidays/locale/en_US/LC_MESSAGES/MO.po (3)

181-204: Proper handling of long translations.

Long translations for complex holiday names are properly formatted across multiple lines for readability while maintaining the correct PO syntax.


13-27: Metadata is correctly structured for the US English locale.

All essential metadata fields are present with appropriate values.


236-242: Clear translation of complex overlapping holiday concept.

Translation successfully captures the concept of overlapping holidays which is important for correct holiday calculation.

holidays/locale/zh_MO/LC_MESSAGES/MO.po (2)

29-104: Empty msgstr fields are correct for this locale.

Empty message strings are appropriate here since the msgid values are already in Traditional Chinese. This follows gettext conventions for source language matching target language.


13-27: Correctly configured metadata for zh_MO locale.

All required metadata fields are present with appropriate values for Macanese Traditional Chinese.

holidays/countries/macau.py (2)

45-45: Confirm references to future legislative documents.

"Lei n.º 27/2024" references a law and year that are in the future. Ensure that citing this document is intended and won't introduce confusion or maintenance overhead if the final legislation differs.


284-366: Refactor large branching logic.

This _populate_government_holidays method has many conditionals handling year-specific cases. Splitting out subroutines or data structures would help maintainability and reduce complexity, as previously suggested.

tests/countries/test_macau.py (1)

609-615: Add tests for leap-lunar-month edge cases.

As previously noted, there are no explicit checks for unusual date shifts when lunar leap months occur near the Mid-Autumn Festival (“Chong Chao”). Consider adding corner cases if the library handles leap-lunar-month divergences.

Comment thread holidays/locale/zh_MO/LC_MESSAGES/MO.po Outdated
Comment thread holidays/locale/en_MO/LC_MESSAGES/MO.po
Comment thread holidays/countries/macau.py Outdated
@KJhellico

Copy link
Copy Markdown
Collaborator

Due to l10n limitations regarding grammars and prepositions, Portuguese translation for Compensatory Rest Days may not 100% match official Macanese government sources i.e. a/o/ao.

I think it's okay. In Spain, we have a similar situation with "Lunes siguiente..." 🤷‍♂️

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4866b5d and a83589a.

📒 Files selected for processing (1)
  • holidays/countries/macau.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
holidays/countries/macau.py (1)
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/countries/macau.py:385-396
Timestamp: 2025-03-04T10:06:09.555Z
Learning: The winter solstice calculation in Macau's holiday implementation uses the same approximation method as Hong Kong's implementation and has been verified against the official Macau calendar for years 2017-2025. The method is valid for years 1952-2099.
🔇 Additional comments (1)
holidays/countries/macau.py (1)

45-45: Confirm reference link accuracy.

Please verify that the link for "Lei n.º 27/2024" remains valid. This future-dated reference may change or move.

Comment thread holidays/countries/macau.py
Comment thread holidays/countries/macau.py
Comment thread holidays/countries/macau.py
Comment thread holidays/countries/macau.py Outdated
@PPsyrius

PPsyrius commented Mar 4, 2025

Copy link
Copy Markdown
Collaborator Author

@coderabbitai help me find possible missing test cases so that we can increase code coverage for our tests back to 100%.

@coderabbitai

coderabbitai Bot commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

Looking at the Macau implementation to understand what we need to test thoroughly.

Now that I have the implementation and existing tests, let's check the coverage to identify which areas are missing tests.

Let me check if there's a project-wide test command we should use to maintain consistency.

Let's also check how test coverage is typically reported in the project:

Now let's look at other test files to understand the testing pattern and coverage expectations:

@PPsyrius Based on my analysis of the Macau implementation and current test coverage, here are the areas that need additional test cases to improve code coverage:

  1. Historical Municipality Coverage:

    • Add tests for both Concelho das Ilhas (I) and Concelho de Macau (M) subdivisions, testing their specific holidays
  2. Subdivision Edge Cases:

    • Test invalid subdivision handling with assertRaises to ensure proper error handling
  3. Year Range Edge Cases:

    • Test holidays at boundary years (1981, 1982, 1985, 2020, etc.) for each category
  4. Language Localization:

    • Test all supported languages (en_MO, en_US, pt_MO, th, zh_CN, zh_MO) with the default_language parameter
  5. Government Holiday Specific Tests:

    • Test the complex logic for SAR Establishment Day and National Day
    • Test government-specific holiday observations and compensatory days
    • Ensure different year ranges for Victory of the Chinese People (2014, 2015, 2020) are tested
  6. Holiday Overrides and Edge Cases:

    • Test all holidays with observed/in-lieu scenarios
    • Verify correct handling of "Liberation of Portugal" for 1974
    • Test the "Implantation of the Republic" logic in different years
  7. Compensatory Rest Days Logic:

    • More explicit testing of the "compensatory rest day" logic, especially for complex holidays like "National Day-Cheung Yeung-Chong Chao"

Here's a code snippet you can add to your test file to increase coverage:

def test_macau_edge_cases(self):
    """Test edge cases for Macau holidays."""
    # Test invalid subdivision
    with self.assertRaises(ValueError):
        holidays.country_holidays("MO", subdiv="XYZ")
    
    # Test boundary years
    mo_government_1981 = holidays.country_holidays("MO", years=1981, categories="GOVERNMENT")
    self.assertNotIn(date(1981, 10, 1), mo_government_1981)  # National Day not observed before 1982
    
    mo_mandatory_1984 = holidays.country_holidays("MO", years=1984, categories="MANDATORY") 
    self.assertNotIn(date(1984, 5, 1), mo_mandatory_1984)  # Labor Day not mandatory before 1985
    
    # Test explicit language setting
    mo_zh = holidays.country_holidays("MO", language="zh_MO")
    self.assertEqual(mo_zh.get(date(2023, 1, 1)), "元旦")
    
    mo_pt = holidays.country_holidays("MO", language="pt_MO")
    self.assertEqual(mo_pt.get(date(2023, 1, 1)), "Fraternidade Universal")
    
    # Test subdivision specific holidays
    mo_i = holidays.country_holidays("MO", subdiv="I", years=2000)
    mo_m = holidays.country_holidays("MO", subdiv="M", years=2000)
    
    # Check for differences between subdivisions
    self.assertIn(date(2000, 6, 10), mo_i)  # Islands Day
    self.assertNotIn(date(2000, 6, 10), mo_m)
    self.assertIn(date(2000, 5, 23), mo_m)  # Macau City Day
    self.assertNotIn(date(2000, 5, 23), mo_i)

def test_government_holiday_special_cases(self):
    """Test special cases for government holidays."""
    # Test the Victory of the Chinese People's War for key years
    mo_govt_2014 = holidays.country_holidays("MO", categories="GOVERNMENT", years=2014)
    mo_govt_2015 = holidays.country_holidays("MO", categories="GOVERNMENT", years=2015)
    mo_govt_2020 = holidays.country_holidays("MO", categories="GOVERNMENT", years=2020)
    
    # 2014 - First year observed
    self.assertIn(date(2014, 9, 3), mo_govt_2014)
    
    # 2015 - 70th Anniversary with different naming
    self.assertIn(date(2015, 9, 3), mo_govt_2015)
    self.assertTrue("70th" in mo_govt_2015.get(date(2015, 9, 3)))
    
    # 2020 - 75th Anniversary
    self.assertIn(date(2020, 9, 3), mo_govt_2020)
    self.assertTrue("75th" in mo_govt_2020.get(date(2020, 9, 3)))
    
    # Test SAR Establishment Day over multiple years to capture naming changes
    mo_govt_1999 = holidays.country_holidays("MO", categories="GOVERNMENT", years=1999)
    mo_govt_2000 = holidays.country_holidays("MO", categories="GOVERNMENT", years=2000)
    mo_govt_2019 = holidays.country_holidays("MO", categories="GOVERNMENT", years=2019)
    
    self.assertIn(date(1999, 12, 20), mo_govt_1999)
    self.assertIn(date(2000, 12, 20), mo_govt_2000)
    self.assertIn(date(2019, 12, 20), mo_govt_2019)
    self.assertTrue("20th" in mo_govt_2019.get(date(2019, 12, 20)))

def test_complex_compensatory_days(self):
    """Test complex compensatory day scenarios."""
    # Test the complex National Day-Cheung Yeung-Chong Chao scenarios
    for year in [2023, 2024, 2025]:
        mo_holidays = holidays.country_holidays("MO", years=year)
        comp_days = [date for date, name in mo_holidays.items() 
                    if "Compensatory" in name and "National Day" in name]
        self.assertTrue(len(comp_days) > 0, f"No compensatory days for National Day in {year}")
    
    # Test other compensatory day logic
    for year in range(2020, 2025):
        mo_holidays = holidays.country_holidays("MO", years=year)
        # Check for Sunday-falling holidays with Monday compensation
        sunday_dates = [date for date in mo_holidays.keys() 
                        if date.weekday() == 6 and not "Compensatory" in mo_holidays.get(date)]
        
        for sunday_date in sunday_dates:
            next_monday = sunday_date + timedelta(days=1)
            if next_monday in mo_holidays:
                self.assertTrue("Compensatory" in mo_holidays.get(next_monday),
                              f"Expected compensatory day on {next_monday} for {sunday_date}")

Additionally, I recommend testing the interaction between different holiday categories more explicitly to ensure they work correctly when combined.

Would you like me to suggest any other specific tests, or would you like more detailed explanations for any of these suggestions?


🏁 Script executed:

#!/bin/bash
# Let's first look at the Macau implementation to understand its structure
echo "Examining Macau implementation file:"
cat holidays/countries/macau.py

Length of output: 17729


🏁 Script executed:

#!/bin/bash
# Look at the current test file to see what's already covered
echo "Examining current Macau test file:"
cat tests/countries/test_macau.py

Length of output: 39453


🏁 Script executed:

#!/bin/bash
# Check if pytest-cov is installed
pip list | grep pytest-cov || pip install pytest-cov

# Run coverage on the Macau tests and get detailed report
python -m pytest --cov=holidays.countries.macau --cov-report=term-missing tests/countries/test_macau.py -v

Length of output: 4135


🏁 Script executed:

#!/bin/bash
# Check for any test instructions in the README or contributing guidelines
cat README.rst | grep -i test
cat CONTRIBUTING.rst 2>/dev/null || echo "No CONTRIBUTING.rst file found"

# Check for any test configuration files
ls -la pytest.ini tox.ini setup.cfg 2>/dev/null

Length of output: 4786


🏁 Script executed:

#!/bin/bash
# Check for coverage configuration
cat .coveragerc 2>/dev/null || echo "No .coveragerc file found"

# Look at GitHub CI workflow files to see how tests are run
ls -la .github/workflows/ 2>/dev/null
cat .github/workflows/*.yml 2>/dev/null | grep -A 10 -B 10 "coverage"

Length of output: 1194


🏁 Script executed:

#!/bin/bash
# Look at a similar test file for another country (e.g., Hong Kong since it was also modified)
cat tests/countries/test_hongkong.py

Length of output: 47667


@PPsyrius After examining your Macau implementation and current test coverage, I've identified several areas that need additional test cases to reach 100% code coverage:

  1. Subdivision Validation and Edge Cases:

    • No tests for invalid subdivision handling
    • Need more thorough testing of subdivision-specific holidays
  2. Year Range Boundaries:

    • Missing tests at critical year boundaries (1981-1982, 1984-1985)
    • Need to test historical municipality transitions (pre/post 1993, pre/post 2000)
  3. Language Localization:

    • Missing explicit tests for th and zh_MO languages
    • No tests with explicit language parameter setting
  4. Complex Holiday Logic:

    • Insufficient coverage for the _winter_solstice_date method branches
    • Missing tests for special cases of compensatory rest days
  5. Special Government Holiday Cases:

    • Limited testing of the National Day-Cheung Yeung-Chong Chao overlap case
    • Not enough tests for anniversary-named holidays (70th/75th anniversaries)

Here's a complete test class you can add to improve coverage:

def test_macau_edge_cases(self):
    """Test edge cases for Macau holidays."""
    # Test invalid subdivision
    with self.assertRaises(ValueError):
        holidays.country_holidays("MO", subdiv="XYZ")
    
    # Test boundary years
    mo_gov_1981 = holidays.country_holidays("MO", years=1981, categories=GOVERNMENT)
    self.assertNoHolidays(mo_gov_1981)  # No holidays before 1982
    
    mo_man_1984 = holidays.country_holidays("MO", years=1984, categories=MANDATORY)
    self.assertNoHolidays(mo_man_1984)  # No mandatory holidays before 1985
    
    # Test explicit language setting for all supported languages
    mo_en_mo = holidays.country_holidays("MO", years=2023, language="en_MO")
    self.assertEqual(mo_en_mo.get(date(2023, 1, 1)), "New Year's Day")
    
    mo_en_us = holidays.country_holidays("MO", years=2023, language="en_US")
    self.assertEqual(mo_en_us.get(date(2023, 1, 1)), "New Year's Day")
    
    mo_pt = holidays.country_holidays("MO", years=2023, language="pt_MO")
    self.assertEqual(mo_pt.get(date(2023, 1, 1)), "Fraternidade Universal")
    
    mo_th = holidays.country_holidays("MO", years=2023, language="th")
    self.assertEqual(mo_th.get(date(2023, 1, 1)), "วันขึ้นปีใหม่")
    
    mo_zh_cn = holidays.country_holidays("MO", years=2023, language="zh_CN")
    self.assertEqual(mo_zh_cn.get(date(2023, 1, 1)), "元旦")
    
    mo_zh_mo = holidays.country_holidays("MO", years=2023, language="zh_MO")
    self.assertEqual(mo_zh_mo.get(date(2023, 1, 1)), "元旦")

def test_winter_solstice_date_calculation(self):
    """Test the winter solstice date calculation logic for all branches."""
    # Test all year % 4 branches
    years_dec_21 = [2016, 2020, 2024, 2028]  # year % 4 == 0 and year >= 1988
    years_dec_22 = [1984, 1988, 1992, 1996]  # year % 4 == 0 but year < 1988 (should be Dec 22)
    
    years_dec_21_mod1 = [2021, 2025, 2029, 2033]  # year % 4 == 1 and year >= 2021
    years_dec_22_mod1 = [2009, 2013, 2017]  # year % 4 == 1 but year < 2021 (should be Dec 22)
    
    years_dec_22_mod2 = [2010, 2014, 2018, 2022, 2026, 2030, 2054]  # year % 4 == 2 and year < 2058
    years_dec_21_mod2 = [2058, 2062, 2066, 2070]  # year % 4 == 2 and year >= 2058 (should be Dec 21)
    
    years_dec_22_mod3 = [2011, 2015, 2019, 2023, 2027, 2087]  # year % 4 == 3 and year < 2091
    years_dec_21_mod3 = [2091, 2095, 2099]  # year % 4 == 3 and year >= 2091 (should be Dec 21)
    
    for year in years_dec_21:
        holidays_year = holidays.country_holidays("MO", years=year)
        self.assertIn(date(year, 12, 21), holidays_year)
        self.assertNotIn(date(year, 12, 22), holidays_year)
    
    for year in years_dec_22:
        holidays_year = holidays.country_holidays("MO", years=year)
        self.assertIn(date(year, 12, 22), holidays_year)
        self.assertNotIn(date(year, 12, 21), holidays_year)
    
    for year in years_dec_21_mod1:
        holidays_year = holidays.country_holidays("MO", years=year)
        self.assertIn(date(year, 12, 21), holidays_year)
        self.assertNotIn(date(year, 12, 22), holidays_year)
    
    for year in years_dec_22_mod1:
        holidays_year = holidays.country_holidays("MO", years=year)
        self.assertIn(date(year, 12, 22), holidays_year)
        self.assertNotIn(date(year, 12, 21), holidays_year)

def test_subdivision_specific_holidays(self):
    """Test subdivision-specific holidays in more detail."""
    # Test Concelho das Ilhas (I) subdivision
    i_1990 = holidays.country_holidays("MO", subdiv="I", years=1990)
    i_1993 = holidays.country_holidays("MO", subdiv="I", years=1993)
    i_1994 = holidays.country_holidays("MO", subdiv="I", years=1994)
    i_1999 = holidays.country_holidays("MO", subdiv="I", years=1999)
    i_2000 = holidays.country_holidays("MO", subdiv="I", years=2000)
    
    # Check holiday before change (Decreto-Lei n.º 15/93/M)
    self.assertIn(date(1990, 11, 30), i_1990)  # Day of Municipality of Ilhas before change
    self.assertIn(date(1992, 11, 30), i_1990)  # Last year before change
    
    # Check transition at 1993
    self.assertNotIn(date(1993, 11, 30), i_1993)
    self.assertIn(date(1993, 7, 13), i_1993)  # Day changed to July 13
    self.assertIn(date(1994, 7, 13), i_1994)
    self.assertIn(date(1999, 7, 13), i_1999)
    
    # Check removal after 1999 (Regulamento Administrativo n.º 4/1999)
    self.assertNotIn(date(2000, 7, 13), i_2000)
    self.assertNotIn(date(2000, 11, 30), i_2000)
    
    # Test Concelho de Macau (M) subdivision
    m_1999 = holidays.country_holidays("MO", subdiv="M", years=1999)
    m_2000 = holidays.country_holidays("MO", subdiv="M", years=2000)
    
    # Check Macau City Day before removal
    self.assertIn(date(1999, 6, 24), m_1999)
    
    # Check removal after 1999
    self.assertNotIn(date(2000, 6, 24), m_2000)
    
    # Test for differences between subdivisions in the same year
    mo_i_2000 = holidays.country_holidays("MO", subdiv="I", years=1995)
    mo_m_2000 = holidays.country_holidays("MO", subdiv="M", years=1995)
    self.assertIn(date(1995, 7, 13), mo_i_2000)  # Islands Day
    self.assertNotIn(date(1995, 7, 13), mo_m_2000)
    self.assertIn(date(1995, 6, 24), mo_m_2000)  # Macau City Day
    self.assertNotIn(date(1995, 6, 24), mo_i_2000)

def test_special_anniversary_holidays(self):
    """Test special anniversary holidays and naming."""
    # Test the 70th Anniversary of the Victory of the Chinese People's War
    mo_govt_2014 = holidays.country_holidays("MO", categories=GOVERNMENT, years=2014)
    mo_govt_2015 = holidays.country_holidays("MO", categories=GOVERNMENT, years=2015)
    mo_govt_2020 = holidays.country_holidays("MO", categories=GOVERNMENT, years=2020)
    
    # 2014 - First year observed but not an anniversary
    self.assertIn(date(2014, 9, 3), mo_govt_2014)
    self.assertFalse("70th" in mo_govt_2014.get(date(2014, 9, 3)))
    
    # 2015 - 70th Anniversary
    self.assertIn(date(2015, 9, 3), mo_govt_2015)
    self.assertTrue("七十" in mo_govt_2015.get(date(2015, 9, 3)))
    
    # Check SAR Establishment Day anniversaries
    mo_govt_1999 = holidays.country_holidays("MO", categories=GOVERNMENT, years=1999)
    mo_govt_2000 = holidays.country_holidays("MO", categories=GOVERNMENT, years=2000)
    mo_govt_2019 = holidays.country_holidays("MO", categories=GOVERNMENT, years=2019)
    
    self.assertIn(date(1999, 12, 20), mo_govt_1999)
    self.assertTrue("回歸祖國" in mo_govt_1999.get(date(1999, 12, 20)))  # Special name for handover
    
    self.assertIn(date(2000, 12, 20), mo_govt_2000)
    self.assertIn(date(2019, 12, 20), mo_govt_2019)
    # 20th anniversary in 2019
    self.assertTrue("20" in str(date(2019, 12, 20).year - 1999))

def test_national_day_cheung_yeung_overlap(self):
    """Test the complex National Day and Cheung Yeung overlap case."""
    # Test the 2020 overlap case specifically mentioned in the PR
    holidays_2020 = holidays.country_holidays("MO", years=2020)
    
    self.assertIn(date(2020, 10, 1), holidays_2020)  # National Day
    self.assertIn(date(2020, 10, 2), holidays_2020)  # Day following + Mid-Autumn Festival
    self.assertIn(date(2020, 10, 5), holidays_2020)  # Special overlap holiday
    
    # Verify the special holiday name
    overlap_holiday = holidays_2020.get(date(2020, 10, 5))
    self.assertTrue("重疊" in overlap_holiday)  # Should contain the overlap text
    
    # Test other years with National Day compensatory days
    for year in [2021, 2022, 2023]:
        mo_holidays = holidays.country_holidays("MO", categories=GOVERNMENT, years=year)
        national_day = date(year, 10, 1)
        
        # Find compensatory days related to National Day
        comp_days = [d for d, name in mo_holidays.items() 
                    if "補假" in name and "國慶日" in name]
        
        self.assertTrue(len(comp_days) > 0, f"No compensatory days for National Day in {year}")

def test_l10n_th(self):
    """Test Thai localization specifically."""
    self.assertLocalizedHolidays(
        "th",
        ("2024-01-01", "วันขึ้นปีใหม่"),
        ("2024-02-09", "วันตรุษจีนตอนบ่าย"),
        ("2024-02-10", "วันตรุษจีน"),
        ("2024-02-11", "วันที่สองของตรุษจีน"),
        ("2024-02-12", "วันที่สามของตรุษจีน"),
        ("2024-02-13", "วันหยุดชดเชยสำหรับวันตรุษจีน"),
        ("2024-02-14", "วันหยุดชดเชยสำหรับวันที่สองของตรุษจีน"),
        ("2024-03-29", "วันศุกร์ประเสริฐ"),
        ("2024-03-30", "วันก่อนวันอีสเตอร์"),
        ("2024-04-01", "วันหยุดชดเชยสำหรับวันก่อนวันอีสเตอร์"),
        ("2024-04-04", "วันเช็งเม้ง"),
        ("2024-05-01", "วันแรงงาน"),
        ("2024-05-15", "วันวิสาขบูชา"),
        ("2024-06-10", "เทศกาลไหว้บ๊ะจ่าง"),
        ("2024-09-18", "วันหลังเทศกาลไหว้พระจันทร์"),
        ("2024-10-01", "วันชาติสาธารณรัฐประชาชนจีน"),
        ("2024-10-02", "วันหลังวันชาติสาธารณรัฐประชาชนจีน"),
        ("2024-10-11", "เทศกาลไหว้ขนมจ้าง"),
        ("2024-11-02", "วันระลึกถึงผู้เสียชีวิต"),
        ("2024-11-04", "วันหยุดชดเชยสำหรับวันระลึกถึงผู้เสียชีวิต"),
        ("2024-12-08", "วันฉลองมารีย์ผู้ปฏิสนธินิรมล"),
        ("2024-12-09", "วันหยุดชดเชยสำหรับวันฉลองมารีย์ผู้ปฏิสนธินิรมล"),
        ("2024-12-20", "วันก่อตั้งเขตบริหารพิเศษมาเก๊า"),
        ("2024-12-21", "วันเข้าฤดูหนาว"),
        ("2024-12-23", "วันหยุดชดเชยสำหรับวันเข้าฤดูหนาว"),
        ("2024-12-24", "วันคริสต์มาสอีฟ"),
        ("2024-12-25", "วันคริสต์มาส"),
        ("2024-12-31", "วันส่งท้ายปีเก่า"),
    )

def test_l10n_zh_mo(self):
    """Test Macanese Traditional Chinese localization specifically."""
    self.assertLocalizedHolidays(
        "zh_MO",
        ("2024-01-01", "元旦"),
        ("2024-02-09", "農曆除夕 (下午)"),
        ("2024-02-10", "農曆正月初一"),
        ("2024-02-11", "農曆正月初二"),
        ("2024-02-12", "農曆正月初三"),
        ("2024-02-13", "農曆正月初一的補假"),
        ("2024-02-14", "農曆正月初二的補假"),
        ("2024-03-29", "耶穌受難日"),
        ("2024-03-30", "復活節前日"),
        ("2024-04-01", "復活節前日的補假"),
        ("2024-04-04", "清明節"),
        ("2024-05-01", "勞動節"),
        ("2024-05-15", "佛誕節"),
        ("2024-06-10", "端午節"),
        ("2024-09-18", "中秋節翌日"),
        ("2024-10-01", "中華人民共和國國慶日"),
        ("2024-10-02", "中華人民共和國國慶日翌日"),
        ("2024-10-11", "重陽節"),
        ("2024-11-02", "追思節"),
        ("2024-11-04", "追思節的補假"),
        ("2024-12-08", "聖母無原罪瞻禮"),
        ("2024-12-09", "聖母無原罪瞻禮的補假"),
        ("2024-12-20", "澳門特別行政區成立紀念日"),
        ("2024-12-21", "冬至"),
        ("2024-12-23", "冬至的補假"),
        ("2024-12-24", "聖誕節前日"),
        ("2024-12-25", "聖誕節"),
        ("2024-12-31", "除夕 (下午)"),
    )

These additional tests will:

  1. Test subdivision validation and holiday date changes
  2. Verify year boundary transitions for holiday categories
  3. Test all supported languages explicitly
  4. Exercise all branches of the Winter Solstice date calculation
  5. Test special anniversary naming conventions
  6. Test the complex National Day/Chung Yeung Festival overlap case
  7. Add comprehensive localization tests for Thai and Traditional Chinese

Let me know if you'd like me to expand on any specific area for even more thorough coverage.

Comment thread holidays/countries/macau.py Outdated
Comment thread holidays/countries/macau.py Outdated
Comment thread holidays/countries/macau.py Outdated
Comment thread holidays/countries/macau.py Outdated
Comment thread holidays/countries/macau.py Outdated
Comment thread holidays/countries/macau.py Outdated
Comment thread tests/countries/test_macau.py Outdated
Comment thread tests/countries/test_macau.py Outdated
Comment thread tests/countries/test_macau.py Outdated
Comment thread tests/countries/test_macau.py Outdated
Comment thread tests/countries/test_macau.py Outdated
Comment thread tests/countries/test_macau.py
Comment thread tests/countries/test_macau.py
@PPsyrius PPsyrius requested a review from KJhellico March 5, 2025 12:56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between edaae22 and b981817.

📒 Files selected for processing (8)
  • holidays/countries/macau.py (1 hunks)
  • holidays/locale/en_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/en_US/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/pt_MO/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/th/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/zh_CN/LC_MESSAGES/MO.po (1 hunks)
  • holidays/locale/zh_MO/LC_MESSAGES/MO.po (1 hunks)
  • tests/countries/test_macau.py (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
holidays/locale/zh_CN/LC_MESSAGES/MO.po (4)
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:38:15.029Z
Learning: For Macau holidays localization, official Macau government sources (e.g., gov.mo) should be the reference for correct terminology, even when it differs from mainland Chinese standards.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:42:43.024Z
Learning: For Macau's Simplified Chinese (zh_CN) localization, the term "重迭" is used on the official government website (gov.mo) for "overlapping" holidays, rather than the mainland standard "重叠".
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/en_MO/LC_MESSAGES/MO.po:86-96
Timestamp: 2025-03-04T10:06:57.171Z
Learning: In Macau holiday localizations, having multiple Chinese variants (聖誕節前日, 聖誕節前夕, 聖誕前夕) for "Christmas Eve" is intentional design, as confirmed by the developer.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:38:15.029Z
Learning: The traditional Chinese script used in Hong Kong, Macau, and Taiwan isn't 100% the same, with regional variations that should be respected in localization files.
holidays/locale/en_US/LC_MESSAGES/MO.po (3)
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:38:15.029Z
Learning: For Macau holidays localization, official Macau government sources (e.g., gov.mo) should be the reference for correct terminology, even when it differs from mainland Chinese standards.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/en_MO/LC_MESSAGES/MO.po:86-96
Timestamp: 2025-03-04T10:06:57.171Z
Learning: In Macau holiday localizations, having multiple Chinese variants (聖誕節前日, 聖誕節前夕, 聖誕前夕) for "Christmas Eve" is intentional design, as confirmed by the developer.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:42:43.024Z
Learning: For Macau's Simplified Chinese (zh_CN) localization, the term "重迭" is used on the official government website (gov.mo) for "overlapping" holidays, rather than the mainland standard "重叠".
holidays/locale/zh_MO/LC_MESSAGES/MO.po (3)
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:38:15.029Z
Learning: For Macau holidays localization, official Macau government sources (e.g., gov.mo) should be the reference for correct terminology, even when it differs from mainland Chinese standards.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/en_MO/LC_MESSAGES/MO.po:86-96
Timestamp: 2025-03-04T10:06:57.171Z
Learning: In Macau holiday localizations, having multiple Chinese variants (聖誕節前日, 聖誕節前夕, 聖誕前夕) for "Christmas Eve" is intentional design, as confirmed by the developer.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:42:43.024Z
Learning: For Macau's Simplified Chinese (zh_CN) localization, the term "重迭" is used on the official government website (gov.mo) for "overlapping" holidays, rather than the mainland standard "重叠".
holidays/locale/en_MO/LC_MESSAGES/MO.po (3)
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:38:15.029Z
Learning: For Macau holidays localization, official Macau government sources (e.g., gov.mo) should be the reference for correct terminology, even when it differs from mainland Chinese standards.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:42:43.024Z
Learning: For Macau's Simplified Chinese (zh_CN) localization, the term "重迭" is used on the official government website (gov.mo) for "overlapping" holidays, rather than the mainland standard "重叠".
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/en_MO/LC_MESSAGES/MO.po:86-96
Timestamp: 2025-03-04T10:06:57.171Z
Learning: In Macau holiday localizations, having multiple Chinese variants (聖誕節前日, 聖誕節前夕, 聖誕前夕) for "Christmas Eve" is intentional design, as confirmed by the developer.
holidays/locale/pt_MO/LC_MESSAGES/MO.po (3)
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:38:15.029Z
Learning: For Macau holidays localization, official Macau government sources (e.g., gov.mo) should be the reference for correct terminology, even when it differs from mainland Chinese standards.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/en_MO/LC_MESSAGES/MO.po:86-96
Timestamp: 2025-03-04T10:06:57.171Z
Learning: In Macau holiday localizations, having multiple Chinese variants (聖誕節前日, 聖誕節前夕, 聖誕前夕) for "Christmas Eve" is intentional design, as confirmed by the developer.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/locale/zh_CN/LC_MESSAGES/MO.po:230-234
Timestamp: 2025-03-04T14:42:43.024Z
Learning: For Macau's Simplified Chinese (zh_CN) localization, the term "重迭" is used on the official government website (gov.mo) for "overlapping" holidays, rather than the mainland standard "重叠".
holidays/countries/macau.py (4)
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/countries/macau.py:284-366
Timestamp: 2025-03-04T11:41:56.389Z
Learning: For Macau holidays implementation, maintaining separate methods for each holiday category (PUBLIC, MANDATORY, GOVERNMENT) is preferred because these categories are based on different sets of laws and have distinct historical evolution.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/countries/macau.py:278-377
Timestamp: 2025-03-05T02:35:03.298Z
Learning: For Macau holiday implementations, it's preferable to maintain separate methods for different holiday categories (MANDATORY, GOVERNMENT, PUBLIC) as they are based on different sets of laws, making the code easier to maintain despite having multiple year-based conditionals.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/countries/macau.py:85-98
Timestamp: 2025-03-04T11:39:34.088Z
Learning: When overriding methods in the holidays library, method signatures should match the parent class declarations, even if some parameters are unused in the child implementation. This is enforced by SonarCloud quality checks.
Learnt from: PPsyrius
PR: vacanza/holidays#2323
File: holidays/countries/macau.py:385-396
Timestamp: 2025-03-04T10:06:09.555Z
Learning: The winter solstice calculation in Macau's holiday implementation uses the same approximation method as Hong Kong's implementation and has been verified against the official Macau calendar for years 2017-2025. The method is valid for years 1952-2099.
🔇 Additional comments (37)
holidays/locale/en_US/LC_MESSAGES/MO.po (5)

1-28: Strong metadata setup for the English localization.

The file header contains all essential metadata for proper gettext functionality, including version, translator details, and encoding information. Using UTF-8 encoding ensures proper handling of all character sets.


85-96: Multiple Christmas Eve translations are intentionally included.

Using three different Chinese variants (聖誕節前日, 聖誕節前夕, 聖誕前夕) for "Christmas Eve" is an intentional design decision as confirmed in the learnings, ensuring proper holiday recognition regardless of which term is used in source materials.

I'm noting that this intentional inclusion supports robust holiday detection across different document sources.


181-187: Long translation spans multiple lines correctly.

The translation for "The Handover of Macau to China and the Establishment of the Macau Special Administrative Region of the People's Republic of China" is properly formatted across multiple lines using the standard gettext continuation format.


205-208: Format string implementation is correct.

The format string "%s的補假" → "Compensatory rest day for %s" follows the proper gettext substitution pattern with the c-format flag, enabling dynamic holiday names to be inserted.


233-242: Overlapping holidays translation is comprehensive.

The translation provides clear explanation of the specific overlapping holiday scenario, making it easy for English speakers to understand this complex calendar situation.

holidays/locale/th/LC_MESSAGES/MO.po (7)

13-28: Thai localization metadata is properly structured.

The file header correctly specifies "th" as the language code with proper project information and character encoding.


83-84: Accurate representation of "Winter Solstice" in Thai.

The translation "วันตงจื้อ(เหมายัน)" includes both the transliterated Chinese term (ตงจื้อ) and the Thai astronomical term (เหมายัน) in parentheses, which provides excellent clarity for Thai speakers.


119-120: Clear Thai translation for Tomb-Sweeping Day.

Using "วันเช็งเม้ง" instead of a direct translation maintains cultural relevance as this term is commonly used in Thailand for this Chinese holiday.


147-148: Culturally appropriate translation for Dragon Boat Festival.

The translation "วันไหว้บ๊ะจ่าง" (Day of Paying Respects to Ba Zhang) focuses on the food aspect of the festival, which is how it's commonly known in Thailand.


185-186: Long Thai translation formats correctly across lines.

The lengthy translation of "The Handover of Macau to China..." is properly formatted across multiple lines, maintaining syntactic clarity in Thai while preserving the gettext format.


204-205: Compact translation for compensatory rest day.

The Thai translation "ชดเชย%s" (compensatory for %s) is concise but clear, typical of Thai language efficiency in translation.


236-238: Clear explanation of overlapping holidays.

The Thai translation explicitly includes the term "หยุดตรงกัน" (holidays coinciding) to clarify the nature of the overlapping holidays.

holidays/locale/zh_CN/LC_MESSAGES/MO.po (4)

13-28: Proper metadata for Simplified Chinese localization.

The file header correctly specifies "zh_CN" as the language code with appropriate metadata for the Simplified Chinese localization.


85-96: Multiple translations for Christmas Eve maintained consistently.

All three variants of Christmas Eve are properly simplified while maintaining the distinct terms, preserving the intentional design decision noted in the learnings.


230-234: Using "重迭" follows Macau's official terminology.

The term "重迭" for overlapping holidays aligns with Macau government sources rather than the mainland standard "重叠", as confirmed in the retrieved learnings.

I acknowledge the intentional use of Macau's official terminology here, respecting regional linguistic differences.


58-60:

Details

❓ Verification inconclusive

Verify translation accuracy for Republic Day.

The translation "葡萄牙共和國國慶日" → "葡萄牙共和国成立日" changes "national day" (國慶日) to "establishment day" (成立日), which slightly differs in meaning.


🏁 Script executed:

#!/bin/bash
# Check if this translation is consistent with official Macau government sources

curl -s "https://www.gov.mo/zh-hans/public-holidays/" | grep -o "葡萄牙共和国.*日"

Length of output: 75


Please verify the official terminology for this holiday translation manually.

  • In holidays/locale/zh_CN/LC_MESSAGES/MO.po (lines 58–60), the translation changes “國慶日” (national day) to “成立日” (establishment day).
  • The automated check using the Macau government public holidays page (via curl and grep) did not yield any evidence to confirm the accuracy of “成立日.”
  • To ensure the translation aligns with the official sources, please manually confirm whether the holiday should be rendered as “國慶日” or “成立日.”
holidays/locale/pt_MO/LC_MESSAGES/MO.po (6)

13-28: Portuguese localization metadata is correctly configured.

The file header specifies "pt_MO" as the language code, properly identifying this as Portuguese specific to Macau region.


119-122: Dual representation for Tomb-Sweeping Day.

The translation includes both the transliterated Chinese name "Cheng Ming" and the descriptive "Dia de Finados" in parentheses, effectively bridging cultural understanding.


155-158: Cultural context provided in Mid-Autumn Festival translation.

Adding "(Bolo Lunar)" to the transliterated "Chong Chao" provides Portuguese speakers with cultural context about the mooncakes central to this festival.


183-189: Long Portuguese translations are correctly formatted.

The multi-line translation for "The Handover of Macau to China..." maintains proper Portuguese grammar and syntax while adhering to gettext format requirements.


207-211: Translation for compensatory rest day is verbose but accurate.

The Portuguese translation "Dia de descanso compensatório relativo ao %s" is more verbose than in other languages but accurately conveys the meaning with proper grammar.


29-32:

Details

✅ Verification successful

Verify the Portuguese term for New Year's Day.

Using "Fraternidade Universal" instead of "Ano Novo" for New Year's Day is unusual. Check if this is the official term used in Macau's Portuguese communications.


🏁 Script executed:

#!/bin/bash
# Check if this is the standard term used in Macau

curl -s "https://www.gov.mo/pt/public-holidays/year-2023/" | grep -o "Fraternidade Universal" || echo "Term not found"

Length of output: 139


Official Term Verified for New Year's Day

The term "Fraternidade Universal" is indeed used on the Macau government website, appearing twice in the 2023 public holidays page. No change is needed as it aligns with the official communication.

holidays/locale/zh_MO/LC_MESSAGES/MO.po (2)

85-96: Multiple Chinese strings for "Christmas Eve".
Noting that three separate msgid entries refer to the same occasion. Based on past discussions, this duplication is intentional for varied naming nuances in Traditional Chinese.


230-246: Correct usage of "重疊" for overlapping.
Using "重疊" aligns with Traditional Chinese usage in Macau references. This practice matches government sources.

holidays/locale/en_MO/LC_MESSAGES/MO.po (2)

86-96: Multiple Chinese strings mapped to "Christmas Eve".
This mapping was previously clarified as intentional to reflect how Chinese naming varies.


150-159: Clear naming of the Double Ninth Festival.
"Chung Yeung Festival (Festival of Ancestors)" helps clarify the meaning behind the holiday.

holidays/countries/macau.py (5)

80-89: Initialization logic is consistent with library patterns.
Defining default observed parameters and invoking super ensures proper configuration for Macau holiday calculations.


232-233: Proper handling for mandatory holidays start year.
Returning early for years <= 1984 prevents unintended holiday entries before the reference decree took effect.


278-283: Year-based gating for government holidays is correct.
Skipping holidays before 2005 aligns with available references, avoiding inconsistent data.


364-377: Well-defined observance handling.
Differentiating Sunday-only and Saturday-Sunday in-lieu rules based on year clarifies transitional policies for Macau.


403-475: Static holiday dictionaries align with established patterns.
The structured data approach for special cases remains consistent and maintainable, matching other country modules.

tests/countries/test_macau.py (6)

20-26: Well-structured test class setup.

The TestMacau class inherits from both CommonCountryTests and TestCase, providing a solid foundation for holiday-specific tests. Initializing different holiday categories (government, mandatory) ensures comprehensive coverage of variations in holiday rules.


30-34: Nice boundary checks for years with no holidays.

Testing years outside defined ranges (1981, 1984, 2004) for each category ensures that the library correctly identifies the absence of holidays before official coverage starts. This is a valuable safeguard for edge cases.


325-442: Thorough coverage of multi-day holiday nuances.

The Chinese New Year block illustrates the library’s complexity, especially around consecutive days, observed days, and partial-day holidays. Having multiple checks for the day-after-changes (like “農曆除夕(下午)”) helps ensure no logic gaps.


720-739: Good handling of in-lieu/observed days for Mid-Autumn Festival.

Ensuring both the standard holiday and its observed or “下一日” day are covered helps clarify multi-day festival logic. The separation of mandatory and public holiday categories here further confirms correctness.


780-788: Appropriate testing for historical municipal subdivisions.

Verifying “澳門市日” before and after 2000 for the 'M' subdivision is essential to reflect historical changes. The usage of separate instances (m_holidays) is clean, highlighting that only relevant subdivisions have these holidays.


1070-1271: Excellent localization coverage.

Your test methods comprehensively verify multiple languages (en_MO, en_US, pt_MO, th, zh_CN, etc.) and compare expected holiday names to the library’s output. This robust approach ensures localized strings remain accurate over time.

Comment thread holidays/locale/pt_MO/LC_MESSAGES/MO.po Outdated
Comment thread tests/countries/test_macau.py
KJhellico
KJhellico previously approved these changes Mar 5, 2025

@KJhellico KJhellico left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

Signed-off-by: Panpakorn Siripanich <19505219+PPsyrius@users.noreply.github.com>
@PPsyrius PPsyrius requested a review from KJhellico March 7, 2025 02:46
@sonarqubecloud

sonarqubecloud Bot commented Mar 7, 2025

Copy link
Copy Markdown

@arkid15r arkid15r left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is absolutely amazing work!

@PPsyrius thanks for adding this and @KJhellico for a great review!

Comment thread tests/countries/test_macau.py
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.

Clarification about Macau subdivision code references

3 participants