Skip to content

Commit

Permalink
2
Browse files Browse the repository at this point in the history
  • Loading branch information
majiidd committed Nov 8, 2024
1 parent 353a148 commit 9c960fe
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 33 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@

# Changelog

## [4.2.0](https://github.com/majiidd/persiantools/compare/4.1.2...4.2.0) (2024-06-28)
## [5.0.0](https://github.com/majiidd/persiantools/compare/4.2.0...5.0.0) 2024-11-08

- Dropped Python 3.8 support; added Python 3.13 compatibility.
- Added type annotations to methods.
- Expanded test suite with new tests.
- Updated dependencies to the latest versions.

## [4.2.0](https://github.com/majiidd/persiantools/compare/4.1.2...4.2.0) 2024-06-28

- Added `CHANGELOG.md` to track changes in the project.

Expand Down
34 changes: 17 additions & 17 deletions persiantools/characters.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
from persiantools import utils
from persiantools.utils import replace

CHARACTER_MAP_AR_TO_FA = {
"دِ": "د",
"بِ": "ب",
"زِ": "ز",
"ذِ": "ذ",
"شِ": "ش",
"سِ": "س",
"ى": "ی",
"ي": "ی",
"ك": "ک",
}

CHARACTER_MAP_FA_TO_AR = {"ی": "ي", "ک": "ك"}


def ar_to_fa(string: str) -> str:
Expand All @@ -21,19 +35,7 @@ def ar_to_fa(string: str) -> str:
if not isinstance(string, str):
raise TypeError("Input must be of type str")

characters_map = {
"دِ": "د",
"بِ": "ب",
"زِ": "ز",
"ذِ": "ذ",
"شِ": "ش",
"سِ": "س",
"ى": "ی",
"ي": "ی",
"ك": "ک",
}

return utils.replace(string, characters_map)
return replace(string, CHARACTER_MAP_AR_TO_FA)


def fa_to_ar(string: str) -> str:
Expand All @@ -56,6 +58,4 @@ def fa_to_ar(string: str) -> str:
if not isinstance(string, str):
raise TypeError("Input must be of type str")

characters_map = {"ی": "ي", "ک": "ك"}

return utils.replace(string, characters_map)
return replace(string, CHARACTER_MAP_FA_TO_AR)
4 changes: 2 additions & 2 deletions persiantools/digits.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import re
from typing import Union

EN_TO_FA_MAP = str.maketrans("0123456789", "۰۱۲۳۴۵۶۷۸۹")
AR_TO_FA_MAP = str.maketrans("٠١٢٣٤٥٦٧٨٩", "۰۱۲۳۴۵۶۷۸۹")
Expand Down Expand Up @@ -231,7 +231,7 @@ def _floating_number_to_word(number: float, depth: bool) -> str:
return _to_word(int(left), False)


def to_word(number: int | float) -> str:
def to_word(number: Union[int, float]) -> str:
"""
Convert a number to its Persian word representation.
Expand Down
24 changes: 12 additions & 12 deletions persiantools/jdatetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ def __format__(self, fmt: str):
def isoweekday(self) -> int:
return self.weekday() + 1

def week_of_year(self):
def week_of_year(self) -> int:
o = JalaliDate(self._year, 1, 1).weekday()
days = self.days_before_month(self._month) + self._day + o

Expand All @@ -693,7 +693,7 @@ def isocalendar(self):
def ctime(self) -> str:
return self.strftime("%c")

def strftime(self, fmt, locale=None):
def strftime(self, fmt: str, locale=None) -> str:
"""
Format a Jalali date according to the given format string.
Expand Down Expand Up @@ -940,19 +940,19 @@ def _check_time_fields(hour, minute, second, microsecond):
raise ValueError("microsecond must be in 0..999999", microsecond)

@property
def hour(self):
def hour(self) -> int:
return self._hour

@property
def minute(self):
def minute(self) -> int:
return self._minute

@property
def second(self):
def second(self) -> int:
return self._second

@property
def microsecond(self):
def microsecond(self) -> int:
return self._microsecond

@property
Expand Down Expand Up @@ -1041,7 +1041,7 @@ def utcnow(cls):
return cls(dt.now(tz=timezone.utc))

@classmethod
def fromisoformat(cls, date_string):
def fromisoformat(cls, date_string: str):
"""Construct a datetime from a string in one of the ISO 8601 formats."""
if not isinstance(date_string, str):
raise TypeError("fromisoformat: argument must be str")
Expand Down Expand Up @@ -1070,7 +1070,7 @@ def fromisoformat(cls, date_string):
return cls(*(date_components + time_components))

@classmethod
def _find_isoformat_datetime_separator(cls, dtstr):
def _find_isoformat_datetime_separator(cls, dtstr: str):
# See the comment in _datetimemodule.c:_find_isoformat_datetime_separator
len_dtstr = len(dtstr)
if len_dtstr == 7:
Expand Down Expand Up @@ -1127,7 +1127,7 @@ def _find_isoformat_datetime_separator(cls, dtstr):
return 8

@classmethod
def _parse_isoformat_time(cls, tstr):
def _parse_isoformat_time(cls, tstr: str):
# Format supported is HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]
len_str = len(tstr)
if len_str < 2:
Expand Down Expand Up @@ -1173,7 +1173,7 @@ def _parse_isoformat_time(cls, tstr):
return time_comps

@classmethod
def _parse_hh_mm_ss_ff(cls, tstr):
def _parse_hh_mm_ss_ff(cls, tstr: str):
# Parses things of the form HH[:?MM[:?SS[{.,}fff[fff]]]]
len_str = len(tstr)

Expand Down Expand Up @@ -1303,7 +1303,7 @@ def ctime(self):

return c

def isoformat(self, sep="T"):
def isoformat(self, sep="T") -> str:
s = "%04d-%02d-%02d%c%02d:%02d:%02d" % (
self.year,
self.month,
Expand Down Expand Up @@ -1607,7 +1607,7 @@ def __repr__(self):
def __str__(self):
return self.isoformat(sep=" ")

def strftime(self, fmt, locale=None):
def strftime(self, fmt: str, locale=None) -> str:
if locale is None or locale not in ["fa", "en"]:
locale = self._locale

Expand Down
13 changes: 12 additions & 1 deletion tests/test_characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ def test_ar_to_fa(self):
"ظ ط ذ د ز ر و ، . ش س ی ب ل ا ت ن م ک ض ص ث ق ف غ ع ه خ ح ؟",
)

self.assertEqual(characters.ar_to_fa(""), "")
self.assertEqual(characters.ar_to_fa("123456"), "123456")
self.assertEqual(characters.ar_to_fa("!@#$%^&*()"), "!@#$%^&*()")
self.assertEqual(characters.ar_to_fa("123 ي"), "123 ی")

with pytest.raises(TypeError):
characters.ar_to_fa(12345)

Expand All @@ -26,14 +31,20 @@ def test_ar_to_fa(self):

def test_fa_to_fa(self):
self.assertEqual(characters.ar_to_fa("السلام علیکم"), "السلام علیکم")
self.assertEqual(characters.ar_to_fa("السلام علیکم"), "السلام علیکم")
self.assertEqual(characters.ar_to_fa("کیک"), "کیک")

def test_fa_to_ar(self):
self.assertEqual(characters.fa_to_ar("کیک"), "كيك")
self.assertEqual(characters.fa_to_ar("سلام به همه"), "سلام به همه")

text = "یکی بود یکی نبود"
expected = "يكي بود يكي نبود"
self.assertEqual(characters.fa_to_ar(text), expected)

self.assertEqual(characters.fa_to_ar(""), "")
self.assertEqual(characters.fa_to_ar("123456"), "123456")
self.assertEqual(characters.fa_to_ar("!@#$%^&*()"), "!@#$%^&*()")
self.assertEqual(characters.fa_to_ar("123 ک"), "123 ك")

with pytest.raises(TypeError):
characters.ar_to_fa(12345)

0 comments on commit 9c960fe

Please sign in to comment.