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
This commit is contained in:
1 parent
31fd3020f4
commit
a612c2988f
15 files changed
+82
-65
No files matched your search
@@ -20,12 +20,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
run: python -m build
|
||||
|
||||
- name: Publish package
|
||||
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.8', '3.9', '3.10']
|
||||
python-version: ['3.10', '3.11', '3.12', '3.13']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -10,3 +10,4 @@ htmlcov
|
||||
.DS_Store
|
||||
venv/
|
||||
.env
|
||||
.python-version
|
||||
@@ -1,6 +1,6 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: check-merge-conflict
|
||||
- id: check-added-large-files
|
||||
@@ -10,7 +10,7 @@ repos:
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/akaihola/darker
|
||||
rev: 1.7.1
|
||||
rev: v2.1.1
|
||||
hooks:
|
||||
- id: darker
|
||||
args:
|
||||
@@ -20,14 +20,14 @@ repos:
|
||||
- --lint=mypy # --strict # commenting strict for now as we haven't maintained typing completely
|
||||
- --lint=pylint --max-line-length=88 --disable=W0511
|
||||
additional_dependencies:
|
||||
- black==23.3.0
|
||||
- flake8==5.0.4
|
||||
- flynt==0.77
|
||||
- isort==5.12.0
|
||||
- mypy==1.3.0
|
||||
- pylint==2.17.4
|
||||
- black==26.1.0
|
||||
- flake8==7.3.0
|
||||
- flynt==1.0.6
|
||||
- isort==7.0.0
|
||||
- mypy==1.19.1
|
||||
- pylint==4.0.4
|
||||
|
||||
- repo: https://github.com/opensource-nepal/commitlint
|
||||
rev: v1.0.0
|
||||
rev: v1.13.3
|
||||
hooks:
|
||||
- id: commitlint
|
||||
@@ -1,5 +1,14 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.2.0
|
||||
|
||||
- **BREAKING**: Drop support for Python 3.8 and 3.9 (EOL)
|
||||
- Add support for Python 3.11, 3.12, and 3.13
|
||||
- Minimum Python version is now 3.10
|
||||
- Modernize type hints to Python 3.10+ syntax (using `X | Y` instead of `Union[X, Y]`)
|
||||
- Update pre-commit hooks to latest versions
|
||||
- Update GitHub Actions workflows to use latest action versions
|
||||
|
||||
## v1.1.3
|
||||
|
||||
- Update months data for year 2082
|
||||
|
||||
@@ -33,7 +33,7 @@ phone_number.parse("+977-9845217789")
|
||||
|
||||
## Requirements
|
||||
|
||||
Python >= 3
|
||||
Python >= 3.10
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import cached_property
|
||||
from typing import Any, Dict, Optional, Union
|
||||
from typing import Any
|
||||
|
||||
from nepali.constants import NEPALI_MONTHS_EN, NEPALI_MONTHS_NE
|
||||
|
||||
|
||||
class NepaliMonthMeta(type):
|
||||
_cache: Dict[int, "nepalimonth"] = {}
|
||||
_cache: dict[int, nepalimonth] = {}
|
||||
|
||||
def __call__(cls, month: Union[int, str], *args, **kwargs) -> "nepalimonth":
|
||||
def __call__(cls, month: int | str, *args, **kwargs) -> nepalimonth:
|
||||
"""
|
||||
Parses the month data and manages the cache.
|
||||
|
||||
@@ -17,7 +19,7 @@ class NepaliMonthMeta(type):
|
||||
:rtype: nepalimonth
|
||||
:raises ValueError: If the given month is invalid.
|
||||
"""
|
||||
value: Optional[int] = None
|
||||
value: int | None = None
|
||||
value = None
|
||||
|
||||
if isinstance(month, int):
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import cached_property
|
||||
from typing import Any, Dict, Optional, Union
|
||||
from typing import Any
|
||||
|
||||
from nepali.constants import WEEKS_ABBR_EN, WEEKS_ABBR_NE, WEEKS_EN, WEEKS_NE
|
||||
|
||||
|
||||
class NepaliWeekMeta(type):
|
||||
_cache: Dict[int, "nepaliweek"] = {}
|
||||
_cache: dict[int, nepaliweek] = {}
|
||||
|
||||
def __call__(cls, week: Union[int, str], *args, **kwargs) -> "nepaliweek":
|
||||
def __call__(cls, week: int | str, *args, **kwargs) -> nepaliweek:
|
||||
"""
|
||||
Parses the week data and manages the cache.
|
||||
|
||||
@@ -17,7 +19,7 @@ class NepaliWeekMeta(type):
|
||||
:rtype: nepaliweek
|
||||
:raises ValueError: If the given week is invalid.
|
||||
"""
|
||||
value: Optional[int] = None
|
||||
value: int | None = None
|
||||
|
||||
if isinstance(week, int):
|
||||
value = int(week)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
"""
|
||||
validates parsing
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import Optional, Tuple
|
||||
|
||||
from nepali.char import nepali_to_english_text
|
||||
from nepali.constants import NEPALI_MONTHS_EN, WEEKS_ABBR_EN, WEEKS_EN
|
||||
@@ -157,7 +158,7 @@ def __convert_12_hour_to_24_hour(hour: int, am_pm: str) -> int:
|
||||
return hour
|
||||
|
||||
|
||||
def __calculate_year(data: dict) -> Optional[int]:
|
||||
def __calculate_year(data: dict) -> int | None:
|
||||
"""Calculates the year value from given data.
|
||||
|
||||
:param data: The dictionary of the format:
|
||||
@@ -217,7 +218,7 @@ def __calculate_day(data: dict) -> int:
|
||||
return 1
|
||||
|
||||
|
||||
def __calculate_hour_minute_seconds(data: dict) -> Tuple[int, int, int, int]:
|
||||
def __calculate_hour_minute_seconds(data: dict) -> tuple[int, int, int, int]:
|
||||
"""Calculates hour, minutes, seconds and microseconds from given data.
|
||||
|
||||
:param data: The dictionary of the format:
|
||||
@@ -256,7 +257,7 @@ def __calculate_hour_minute_seconds(data: dict) -> Tuple[int, int, int, int]:
|
||||
return hour, minute, second, fraction
|
||||
|
||||
|
||||
def __calculate_weekday(data: dict) -> Optional[nepaliweek]:
|
||||
def __calculate_weekday(data: dict) -> nepaliweek | None:
|
||||
"""Calculates the weekday of the date given in data.
|
||||
|
||||
:param data: The data that describes the date.
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
from typing import List, Tuple
|
||||
|
||||
from .models import District, Municipality, MunicipalityType, Province
|
||||
|
||||
|
||||
def _loadData() -> Tuple[List[Province], List[District], List[Municipality]]:
|
||||
def _loadData() -> tuple[list[Province], list[District], list[Municipality]]:
|
||||
from ._data import _location_data
|
||||
|
||||
provinces = []
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from enum import Enum
|
||||
from typing import List
|
||||
|
||||
|
||||
class Location:
|
||||
@@ -37,11 +36,11 @@ class Province(Location):
|
||||
self.__municipalities.append(municipality)
|
||||
|
||||
@property
|
||||
def districts(self) -> List["District"]:
|
||||
def districts(self) -> list["District"]:
|
||||
return self.__districts
|
||||
|
||||
@property
|
||||
def municipalities(self) -> List["Municipality"]:
|
||||
def municipalities(self) -> list["Municipality"]:
|
||||
return self.__municipalities
|
||||
|
||||
|
||||
@@ -61,7 +60,7 @@ class District(Location):
|
||||
return self.__province
|
||||
|
||||
@property
|
||||
def municipalities(self) -> List["Municipality"]:
|
||||
def municipalities(self) -> list["Municipality"]:
|
||||
return self.__municipalities
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
Contains the class for the nepalinumber feature
|
||||
"""
|
||||
|
||||
from typing import Any, Tuple, Type, Union
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from .utils import NP_NUMBERS, NP_NUMBERS_SET, english_to_nepali
|
||||
|
||||
@@ -21,7 +23,7 @@ class nepalinumber:
|
||||
self.__value = self.__parse(value)
|
||||
|
||||
def get_parse_exception(
|
||||
self, obj: object, ex_class: Type[Exception] = ValueError
|
||||
self, obj: object, ex_class: type[Exception] = ValueError
|
||||
) -> Exception:
|
||||
"""
|
||||
Returns the exception object to be raised when the parse is failed.
|
||||
@@ -30,7 +32,7 @@ class nepalinumber:
|
||||
:param obj: Object that is failed during the parse
|
||||
:type obj: object
|
||||
:param ex_class: Exception class type to be returned, defaults to ValueError
|
||||
:type ex_class: Type[Exception], optional
|
||||
:type ex_class: type[Exception], optional
|
||||
:return: Exception object to be raised
|
||||
:rtype: Exception
|
||||
"""
|
||||
@@ -38,7 +40,7 @@ class nepalinumber:
|
||||
f"could not convert {obj.__class__.__name__} to {self.__class__.__name__}: '{obj}'"
|
||||
)
|
||||
|
||||
def __parse(self, value: Any) -> Union[int, float]:
|
||||
def __parse(self, value: Any) -> int | float:
|
||||
"""
|
||||
Parses nepali number input into a valid value.
|
||||
|
||||
@@ -68,7 +70,7 @@ class nepalinumber:
|
||||
|
||||
return self.__parse_object(value)
|
||||
|
||||
def __parse_str(self, value: str) -> Union[int, float]:
|
||||
def __parse_str(self, value: str) -> int | float:
|
||||
"""
|
||||
Parses str object into int and float.
|
||||
This is a low level implementation.
|
||||
@@ -112,7 +114,7 @@ class nepalinumber:
|
||||
i += 1
|
||||
return sign * result
|
||||
|
||||
def __parse_object(self, obj: Any) -> Union[int, float]:
|
||||
def __parse_object(self, obj: Any) -> int | float:
|
||||
"""
|
||||
Parses object using __int__, __float__, and __str__.
|
||||
|
||||
@@ -129,7 +131,7 @@ class nepalinumber:
|
||||
# object conversion must raise TypeError if fails
|
||||
raise self.get_parse_exception(obj, ex_class=TypeError) from None
|
||||
|
||||
def __convert_or_return(self, obj) -> Union["nepalinumber", object]:
|
||||
def __convert_or_return(self, obj) -> nepalinumber | object:
|
||||
"""
|
||||
Will try to parse the given object and convert to nepalinumber
|
||||
else will return the same object
|
||||
@@ -165,7 +167,7 @@ class nepalinumber:
|
||||
"""
|
||||
return float(self.__value)
|
||||
|
||||
def __add(self, other) -> Union[int, float]:
|
||||
def __add(self, other) -> int | float:
|
||||
"""
|
||||
Adds the value in the object with the passed object
|
||||
|
||||
@@ -179,7 +181,7 @@ class nepalinumber:
|
||||
|
||||
return self.__value + other
|
||||
|
||||
def __mul(self, other) -> Union[int, float]:
|
||||
def __mul(self, other) -> int | float:
|
||||
"""
|
||||
Multiplies the value in the object with the passed object
|
||||
|
||||
@@ -219,13 +221,13 @@ class nepalinumber:
|
||||
|
||||
return self.__value != other
|
||||
|
||||
def __neg__(self) -> "nepalinumber":
|
||||
def __neg__(self) -> nepalinumber:
|
||||
"""
|
||||
Returns the negative value of the nepalinumber value
|
||||
"""
|
||||
return nepalinumber((-1) * self.__value)
|
||||
|
||||
def __add__(self, other) -> Union["nepalinumber", object]:
|
||||
def __add__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the addition operator + is used after
|
||||
the nepalinumber object
|
||||
@@ -242,7 +244,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __radd__(self, other) -> Union["nepalinumber", object]:
|
||||
def __radd__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the addition operator + is used before
|
||||
the nepalinumber object
|
||||
@@ -259,7 +261,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __sub__(self, other) -> Union["nepalinumber", object]:
|
||||
def __sub__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the subtraction operator - is used after
|
||||
the nepalinumber object
|
||||
@@ -278,7 +280,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __rsub__(self, other) -> Union["nepalinumber", object]:
|
||||
def __rsub__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the subtraction operator - is used before
|
||||
the nepalinumber object
|
||||
@@ -298,7 +300,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __mul__(self, other) -> Union["nepalinumber", object]:
|
||||
def __mul__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the multiplication operator * is used after
|
||||
the nepalinumber object
|
||||
@@ -318,7 +320,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __rmul__(self, other) -> Union["nepalinumber", object]:
|
||||
def __rmul__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the multiplication operator * is used before
|
||||
the nepalinumber object
|
||||
@@ -338,7 +340,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __truediv__(self, other) -> Union["nepalinumber", object]:
|
||||
def __truediv__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the division operator / is used after
|
||||
the nepalinumber object
|
||||
@@ -357,7 +359,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __rtruediv__(self, other) -> Union["nepalinumber", object]:
|
||||
def __rtruediv__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the division operator / is used before
|
||||
the nepalinumber object
|
||||
@@ -377,7 +379,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __floordiv__(self, other) -> Union["nepalinumber", object]:
|
||||
def __floordiv__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the floor/integer division operator // is used
|
||||
after the nepalinumber object
|
||||
@@ -396,7 +398,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __rfloordiv__(self, other) -> Union["nepalinumber", object]:
|
||||
def __rfloordiv__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the floor/integer division operator // is used
|
||||
before the nepalinumber object
|
||||
@@ -416,7 +418,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __mod__(self, other) -> Union["nepalinumber", object]:
|
||||
def __mod__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the modulo operator % is used after
|
||||
the nepalinumber object
|
||||
@@ -436,7 +438,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __rmod__(self, other) -> Union["nepalinumber", object]:
|
||||
def __rmod__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the modulo operator % is used before
|
||||
the nepalinumber object
|
||||
@@ -458,7 +460,7 @@ class nepalinumber:
|
||||
|
||||
def __divmod__(
|
||||
self, other
|
||||
) -> Tuple[Union["nepalinumber", object], Union["nepalinumber", object]]:
|
||||
) -> tuple[nepalinumber | object, nepalinumber | object]:
|
||||
"""
|
||||
Called when the built-in function divmod() is used
|
||||
with nepalinumber as the dividend and other as divisor
|
||||
@@ -483,7 +485,7 @@ class nepalinumber:
|
||||
|
||||
def __rdivmod__(
|
||||
self, other
|
||||
) -> Tuple[Union["nepalinumber", object], Union["nepalinumber", object]]:
|
||||
) -> tuple[nepalinumber | object, nepalinumber | object]:
|
||||
"""
|
||||
Called when the built-in function divmod() is used
|
||||
with nepalinumber as the divisor and other as dividend
|
||||
@@ -506,7 +508,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __pow__(self, other) -> Union["nepalinumber", object]:
|
||||
def __pow__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the power operator ** is used after
|
||||
the nepalinumber object
|
||||
@@ -526,7 +528,7 @@ class nepalinumber:
|
||||
except TypeError:
|
||||
return NotImplemented
|
||||
|
||||
def __rpow__(self, other) -> Union["nepalinumber", object]:
|
||||
def __rpow__(self, other) -> nepalinumber | object:
|
||||
"""
|
||||
Called when the power operator ** is used before
|
||||
the nepalinumber object
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import re
|
||||
from enum import Enum
|
||||
from typing import Union
|
||||
|
||||
_mobile_number_re = re.compile(r"^(?:\+977|977)?(?:-)?(?:98|97|96)\d{8}$")
|
||||
_landline_number_re = re.compile(
|
||||
@@ -93,7 +92,7 @@ def parse(number: str):
|
||||
return None
|
||||
|
||||
|
||||
def _get_operator(number: str) -> Union[Operator, None]:
|
||||
def _get_operator(number: str) -> Operator | None:
|
||||
"""
|
||||
Returns operator from the number.
|
||||
NOTE: The number should be 10digit mobile number.
|
||||
|
||||
+1
-2
@@ -1,5 +1,4 @@
|
||||
import datetime
|
||||
from typing import Union
|
||||
|
||||
from .constants import NEPAL_TIMEZONE
|
||||
|
||||
@@ -28,7 +27,7 @@ class NepaliTimeZone(datetime.tzinfo):
|
||||
return isinstance(o, self.__class__)
|
||||
|
||||
|
||||
def get_timezone() -> Union[datetime.tzinfo, None]:
|
||||
def get_timezone() -> datetime.tzinfo | None:
|
||||
"""
|
||||
Returns current device's timezone.
|
||||
Timezone of the machine.
|
||||
|
||||
@@ -38,7 +38,7 @@ if sys.argv[-1] == "publish":
|
||||
|
||||
setuptools.setup(
|
||||
name="nepali",
|
||||
version="1.1.3",
|
||||
version="1.2.0",
|
||||
license="MIT",
|
||||
author="opensource-nepal",
|
||||
author_email="aj3sshh@gmail.com, sugatbajracharya49@gmail.com",
|
||||
@@ -57,9 +57,14 @@ setuptools.setup(
|
||||
url=GITHUB_URL,
|
||||
packages=setuptools.find_packages(exclude=["tests*"]),
|
||||
test_suite="nepali.tests",
|
||||
python_requires=">=3.10",
|
||||
install_requires=[],
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user