Files
py-nepali/nepali/datetime/_nepalimonth.py
T
Sugat Bajracharya a612c2988f feat!: drop Python 3.8/3.9 support, add 3.11-3.13
BREAKING CHANGE: Minimum Python version is now 3.10

- Drop support for Python 3.8 (EOL Oct 2024) and 3.9 (EOL Oct 2025)
- Add support for Python 3.11, 3.12, and 3.13
- Modernize type hints to Python 3.10+ syntax
- Update pre-commit hooks to latest versions
- Update GitHub Actions to latest versions
- Bump version to 1.2.0
2026-01-30 22:23:46 +05:45

119 lines
3.1 KiB
Python

from __future__ import annotations
from functools import cached_property
from typing import Any
from nepali.constants import NEPALI_MONTHS_EN, NEPALI_MONTHS_NE
class NepaliMonthMeta(type):
_cache: dict[int, nepalimonth] = {}
def __call__(cls, month: int | str, *args, **kwargs) -> nepalimonth:
"""
Parses the month data and manages the cache.
:param month: An integer or string representing the month.
:type month: Union[int, str]
:return: An instance of the nepalimonth class representing the given month.
:rtype: nepalimonth
:raises ValueError: If the given month is invalid.
"""
value: int | None = None
value = None
if isinstance(month, int):
value = int(month)
elif isinstance(month, str):
try:
value = cls._parse_str(month)
except ValueError:
pass
# checking if month is valid
if value is None or value < 1 or value > 12:
raise ValueError(f"Invalid month: {month}")
# checking cache
if value not in cls._cache:
cls._cache[value] = super(NepaliMonthMeta, cls).__call__(
value, *args, **kwargs
)
return cls._cache[value]
@staticmethod
def _parse_str(month: str) -> int:
"""
Parses str value of the month and returns int.
:param month: A string representing the month.
:type month: str
:return: An integer representing the month.
:rtype: int
:raises ValueError: If the given string does not represent a valid month.
"""
if month.isdigit():
return int(month)
month = month.capitalize()
month_names = NEPALI_MONTHS_EN + NEPALI_MONTHS_NE
try:
index = month_names.index(month)
except ValueError:
raise ValueError(f"Invalid month name: {month}")
return (index % 12) + 1
class nepalimonth(metaclass=NepaliMonthMeta):
"""
Represents Nepali month: Baishakh, Jestha, ..., Chaitra.
Baishakh: 1,
Jestha: 2,
...
Chaitra: 12
>>> nepalimonth(1)
>>> nepalimonth("Baishakh")
>>> nepalimonth("बैशाख")
:param Union[int, str] month: Month data to be parsed.
:raises ValueError: The value is invalid.
"""
def __init__(self, month) -> None:
self.__value = month
def __str__(self) -> str:
return self.name
def __repr__(self) -> str:
return f"<nepalimonth: {self.__value}>"
def __int__(self) -> int:
return self.value
def __eq__(self, other: Any) -> bool:
if isinstance(other, nepalimonth):
return self.value == other.value
elif isinstance(other, int):
return self.value == other
return False
@cached_property
def value(self) -> int:
return self.__value
@cached_property
def name(self) -> str:
"""Month's english name"""
return NEPALI_MONTHS_EN[self.__value - 1]
@cached_property
def name_ne(self) -> str:
"""Month's nepali name"""
return NEPALI_MONTHS_NE[self.__value - 1]