Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-jdatetime for 
openSUSE:Factory checked in at 2022-06-24 08:45:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-jdatetime (Old)
 and      /work/SRC/openSUSE:Factory/.python-jdatetime.new.1548 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-jdatetime"

Fri Jun 24 08:45:01 2022 rev:5 rq:984627 version:4.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-jdatetime/python-jdatetime.changes        
2022-01-29 20:57:27.800509584 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-jdatetime.new.1548/python-jdatetime.changes  
    2022-06-24 08:45:10.499130066 +0200
@@ -1,0 +2,13 @@
+Thu Jun 23 01:06:35 UTC 2022 - Yogalakshmi Arunachalam <[email protected]>
+
+- Update to 4.1.0
+  * Add support for %z directive in ``jdatetime.datetime.strptime`
+  * Add support for %b and %B directive directive in 
``jdatetime.datetime.strptime`
+  Changed
+  * Potential breaking change: Replace spaces with ZWNJ (???????????????????) 
in output of ``jdatetime.datetime.strftime`
+- Update to 4.0.0: 
+  * Add fold attribute to jdatetime.datetime
+  * Change
+  * Drop Python < 3.7 support
+
+-------------------------------------------------------------------

Old:
----
  v3.8.2.tar.gz

New:
----
  v4.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-jdatetime.spec ++++++
--- /var/tmp/diff_new_pack.BdQ6Gp/_old  2022-06-24 08:45:10.991130617 +0200
+++ /var/tmp/diff_new_pack.BdQ6Gp/_new  2022-06-24 08:45:10.995130621 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-jdatetime
-Version:        3.8.2
+Version:        4.1.0
 Release:        0
 Summary:        Jalali datetime binding for python
 License:        Python-2.0

++++++ v3.8.2.tar.gz -> v4.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/.github/workflows/test.yml 
new/python-jalali-4.1.0/.github/workflows/test.yml
--- old/python-jalali-3.8.2/.github/workflows/test.yml  2022-01-24 
20:05:29.000000000 +0100
+++ new/python-jalali-4.1.0/.github/workflows/test.yml  2022-03-22 
15:07:54.000000000 +0100
@@ -12,7 +12,7 @@
     strategy:
       matrix:
         os: [ubuntu-latest]
-        python-version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"]
+        python-version: ["3.7", "3.8", "3.9", "3.10"]
     name: OS ${{ matrix.os}} - Python ${{ matrix.python-version }}
     steps:
       - uses: actions/checkout@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/CHANGELOG.md 
new/python-jalali-4.1.0/CHANGELOG.md
--- old/python-jalali-3.8.2/CHANGELOG.md        2022-01-24 20:05:29.000000000 
+0100
+++ new/python-jalali-4.1.0/CHANGELOG.md        2022-03-22 15:07:54.000000000 
+0100
@@ -1,5 +1,19 @@
 # Changelog
 
+## [4.1.0] - 2022-03-22
+### Add
+* Add support for ``%z`` directive in ``jdatetime.datetime.strptime`
+* Add support for ``%b`` and ``%B`` directive directive in 
``jdatetime.datetime.strptime`
+### Changed 
+* Potential breaking change: Replace spaces with ZWNJ (???????????????????) in 
output of ``jdatetime.datetime.strftime`
+
+## [4.0.0] - 2022-02-14
+### Add
+* Add ``fold`` attribute to ``jdatetime.datetime``
+
+### Change
+* Drop Python < 3.7 support
+
 ## [3.8.2] - 2022-01-24
 ### Fixed
 * Fix older version objects unpickling problem
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/README.rst 
new/python-jalali-4.1.0/README.rst
--- old/python-jalali-3.8.2/README.rst  2022-01-24 20:05:29.000000000 +0100
+++ new/python-jalali-4.1.0/README.rst  2022-03-22 15:07:54.000000000 +0100
@@ -1,5 +1,6 @@
 jdatetime
 =========
+
 jdatetime is Jalali_ implementation of Python's datetime module
 
 Status
@@ -24,7 +25,7 @@
 
 Documents
 ---------
-This module exactly follows Python Standard datetime module's methods 
http://docs.python.org/release/2.7.1/library/datetime.html
+This module exactly follows Python Standard datetime module's methods 
http://docs.python.org/release/3.7.1/library/datetime.html
 
 Also these methods are added to jdatetime.date and jdatetime.datetime :
 
@@ -43,17 +44,11 @@
         algortim is based on http://en.wikipedia.org/wiki/Leap_year
 
 
-
 Example
 -------
 
 .. code-block:: shell
 
-    $ python
-    Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39)
-    [GCC 4.4.5] on linux2
-    Type "help", "copyright", "credits" or "license" for more information.
-    (InteractiveConsole)
     >>> import jdatetime
     >>> jdatetime.datetime.now()
     jdatetime.datetime(1394, 12, 4, 8, 37, 31, 855729)
@@ -87,11 +82,6 @@
 
 .. code-block:: shell
 
-    $ python
-    Python 2.7.9 (default, Mar  1 2015, 12:57:24)
-    [GCC 4.9.2] on linux2
-    Type "help", "copyright", "credits" or "license" for more information.
-    (InteractiveConsole)
     >>> import locale
     >>> import jdatetime
     >> jdatetime.datetime.now().strftime("%a, %d %b %Y %H:%M:%S")
@@ -147,7 +137,7 @@
 
 Release Steps
 ~~~~~~~~~~~~~~
-* Bump the version in `setup.py` and `jdatetime/__init__.py`. We are using 
Semantic Versioning.
+* Bump the version in ``setup.py`` and ``jdatetime/__init__.py``. We are using 
Semantic Versioning.
 * Add release notes in CHANGELOG.md
 * Commit and push the changes. Create a PR
 * After the PR is merged, create a release with a tag name like `v<version>`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/appveyor.yml 
new/python-jalali-4.1.0/appveyor.yml
--- old/python-jalali-3.8.2/appveyor.yml        2022-01-24 20:05:29.000000000 
+0100
+++ new/python-jalali-4.1.0/appveyor.yml        2022-03-22 15:07:54.000000000 
+0100
@@ -2,9 +2,6 @@
 
 environment:
   matrix:
-    - PYTHON: "C:\\Python27"
-    - PYTHON: "C:\\Python33"
-    - PYTHON: "C:\\Python34"
     - PYTHON: "C:\\Python37"
     - PYTHON: "C:\\Python38"
     - PYTHON: "C:\\Python39"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/jdatetime/__init__.py 
new/python-jalali-4.1.0/jdatetime/__init__.py
--- old/python-jalali-3.8.2/jdatetime/__init__.py       2022-01-24 
20:05:29.000000000 +0100
+++ new/python-jalali-4.1.0/jdatetime/__init__.py       2022-03-22 
15:07:54.000000000 +0100
@@ -1,30 +1,24 @@
-# -*- coding: utf-8 -*-
 # jdatetime is (c) 2010-2011 Milad Rastian <eslashmili at gmail.com>.
 # The jdatetime module was contributed to Python as of Python 2.7 and thus
 # was licensed under the Python license. Same license applies to all files in
 # the jdatetime package project.
-from __future__ import unicode_literals
 
 import datetime as py_datetime
 import locale as _locale
 import platform
-import re as _re
-import sys
+import re
 from functools import partial as _partial
 
 try:
     from greenlet import getcurrent as get_ident
 except ImportError:
-    try:
-        from _thread import get_ident
-    except ImportError:
-        from thread import get_ident  # Python 2 used thread module instead of 
_thread
+    from _thread import get_ident
 
 from jdatetime.jalali import (
     GregorianToJalali, JalaliToGregorian, j_days_in_month,
 )
 
-__VERSION__ = "3.8.2"
+__VERSION__ = "4.1.0"
 MINYEAR = 1
 MAXYEAR = 9377
 
@@ -61,34 +55,12 @@
 timedelta = py_datetime.timedelta
 tzinfo = py_datetime.tzinfo
 
-timestamp_is_supported = (
-    hasattr(py_datetime.datetime, 'timestamp') and
-    callable(py_datetime.datetime.timestamp)
-)
-
-if sys.version_info[0] >= 3:  # py3
-    _int_types = (int,)
-    _basestring = str
-else:
-    _int_types = (int, long)  # noqa
-    _basestring = basestring  # noqa: F821
-
 if platform.system() == 'Windows':
     FA_LOCALE = 'Persian_Iran'
 else:
     FA_LOCALE = 'fa_IR'
 
 
-if sys.version_info[:2] < (3, 7):
-    # Prior to Python 3.7, `%` is escaped by re.escape. We don't want that.
-    def _escape(pattern):
-        if isinstance(pattern, bytes):  # only happens in Python 2
-            pattern = pattern.decode()
-        return _re.escape(pattern).replace(r'\%', '%')
-else:
-    _escape = _re.escape
-
-
 def _format_time(hour, minute, second, microsecond, timespec='auto'):
     specs = {
         'hours': '{:02d}',
@@ -115,7 +87,7 @@
 
 class time(py_datetime.time):
     def __repr__(self):
-        return "jdatetime.time(%s, %s, %s)" % (self.hour, self.minute, 
self.second)
+        return f"jdatetime.time({self.hour}, {self.minute}, {self.second})"
 
 
 _thread_local_locales = dict()
@@ -149,7 +121,7 @@
     return _thread_local_locales.get(get_ident())
 
 
-class date(object):
+class date:
     """date(year, month, day) --> date object"""
     j_months_en = [
         'Farvardin',
@@ -199,29 +171,29 @@
     ]
     j_ampm_en = {'PM': 'PM', 'AM': 'AM'}
     j_months_fa = [
-        u'??????????????',
-        u'????????????????',
-        u'??????????',
-        u'??????',
-        u'??????????',
-        u'????????????',
-        u'??????',
-        u'????????',
-        u'??????',
-        u'????',
-        u'????????',
-        u'??????????',
+        '??????????????',
+        '????????????????',
+        '??????????',
+        '??????',
+        '??????????',
+        '????????????',
+        '??????',
+        '????????',
+        '??????',
+        '????',
+        '????????',
+        '??????????',
     ]
     j_weekdays_fa = [
-        u'????????',
-        u'????????????',
-        u'????????????',
-        u'???? ????????',
-        u'????????????????',
-        u'??????????????',
-        u'????????',
+        '????????',
+        '???????????????',
+        '????????????',
+        '???????????????',
+        '????????????????',
+        '?????????????????',
+        '????????',
     ]
-    j_ampm_fa = {'PM': u'?????? ???? ??????', 'AM': u'?????? ???? ??????'}
+    j_ampm_fa = {'PM': '?????? ???? ??????', 'AM': '?????? ???? ??????'}
 
     @property
     def year(self):
@@ -253,7 +225,7 @@
     __locale = None
 
     def _check_arg(self, value):
-        if isinstance(value, _int_types):
+        if isinstance(value, int):
             return True
         return False
 
@@ -376,8 +348,20 @@
         (y, m, d) = GregorianToJalali(d.year, d.month, d.day).getJalaliList()
         return date(y, m, d)
 
+    @staticmethod
+    def j_month_to_num(month_name):
+        return date.j_months_en.index(month_name.lower().capitalize()) + 1
+
+    @staticmethod
+    def j_month_short_to_num(month_name):
+        return date.j_months_short_en.index(month_name.lower().capitalize()) + 
1
+
+    @staticmethod
+    def j_month_fa_to_num(month_name):
+        return date.j_months_fa.index(month_name) + 1
+
     def __repr__(self):
-        return "jdatetime.date(%s, %s, %s)" % (self.year, self.month, self.day)
+        return f"jdatetime.date({self.year}, {self.month}, {self.day})"
 
     def __str__(self):
         return self.strftime("%Y-%m-%d")
@@ -646,7 +630,7 @@
         for s, r in symbols.items():
             format = format.replace(s, r)
 
-        for symbol in _re.findall("\%-?[a-zA-z-]", format):
+        for symbol in re.findall(r"\%-?[a-zA-z-]", format):
             if symbol in STRFTIME_MAPPING:
                 replace_method_name, kwargs = STRFTIME_MAPPING[symbol]
                 kwargs.update({"format": format, "symbol": symbol})
@@ -664,20 +648,22 @@
 date.max = date(MAXYEAR, 12, 30)
 
 _DIRECTIVE_PATTERNS = {
-    '%Y': '(?P<Y>[0-9]{4})',
-    '%y': '(?P<y>[0-9]{2})',
-    '%m': '(?P<m>[0-9]{1,2})',
-    '%d': '(?P<d>[0-9]{1,2})',
-    '%H': '(?P<H>[0-9]{1,2})',
-    '%M': '(?P<M>[0-9]{1,2})',
-    '%S': '(?P<S>[0-9]{1,2})',
-    '%f': '(?P<f>[0-9]{1,6})',
+    '%Y': '(?P<Y>\d{4})',
+    '%y': '(?P<y>\d{2})',
+    '%m': '(?P<m>\d{1,2})',
+    '%d': '(?P<d>\d{1,2})',
+    '%H': '(?P<H>\d{1,2})',
+    '%M': '(?P<M>\d{1,2})',
+    '%S': '(?P<S>\d{1,2})',
+    '%f': '(?P<f>\d{1,6})',
+    '%B': '(?P<B>[a-zA-Z\u0600-\u06EF\uFB8A\u067E\u0686\u06AF]{3,12})',
+    '%b': '(?P<b>[a-zA-Z]{3})',
+    '%z': 
'(?P<z>[+-]\d\d:?[0-5\u06F0-\u06F5]\d(:?[0-5\u06F0-\u06F5]\d(\.\d{1,6})?)?)',
 }
 
-
 # Replace directives with patterns according to _DIRECTIVE_PATTERNS
 _directives_to_pattern = _partial(
-    _re.compile('|'.join(_DIRECTIVE_PATTERNS)).sub,
+    re.compile('|'.join(_DIRECTIVE_PATTERNS)).sub,
     lambda match: _DIRECTIVE_PATTERNS[match.group()]
 )
 
@@ -690,7 +676,7 @@
 
     def time(self):
         """Return time object with same time but with tzinfo=None."""
-        return time(self.hour, self.minute, self.second, self.microsecond)
+        return time(self.hour, self.minute, self.second, self.microsecond, 
fold=self.fold)
 
     def date(self):
         """Return date object with same year, month and day."""
@@ -705,7 +691,10 @@
         minute=None,
         second=None,
         microsecond=None,
-        tzinfo=None, **kwargs
+        tzinfo=None,
+        *,
+        fold=0,
+        **kwargs,
     ):
         date.__init__(self, year, month, day, **kwargs)
         tmp_hour = 0
@@ -721,6 +710,10 @@
         if microsecond is not None:
             tmp_micr = microsecond
 
+        if fold not in (0, 1):
+            raise ValueError('fold must be either 0 or 1', fold)
+        self._fold = fold
+
         if not (
             self._check_arg(tmp_hour) and
             self._check_arg(tmp_min) and
@@ -729,11 +722,11 @@
         ):
             raise TypeError("an integer is required")
 
-        self.__time = time(tmp_hour, tmp_min, tmp_sec, tmp_micr, tzinfo)
+        self.__time = time(tmp_hour, tmp_min, tmp_sec, tmp_micr, tzinfo, 
fold=fold)
 
     def __repr__(self):
         if self.__time.tzinfo is not None:
-            return "jdatetime.datetime(%s, %s, %s, %s, %s, %s, %s, tzinfo=%s)" 
% (
+            return "jdatetime.datetime({}, {}, {}, {}, {}, {}, {}, 
tzinfo={})".format(
                 self.year,
                 self.month,
                 self.day, self.hour,
@@ -744,7 +737,7 @@
             )
 
         if self.__time.microsecond != 0:
-            return "jdatetime.datetime(%s, %s, %s, %s, %s, %s, %s)" % (
+            return "jdatetime.datetime({}, {}, {}, {}, {}, {}, {})".format(
                 self.year,
                 self.month,
                 self.day,
@@ -755,7 +748,7 @@
             )
 
         if self.__time.second != 0:
-            return "jdatetime.datetime(%s, %s, %s, %s, %s, %s)" % (
+            return "jdatetime.datetime({}, {}, {}, {}, {}, {})".format(
                 self.year,
                 self.month,
                 self.day,
@@ -764,7 +757,7 @@
                 self.second,
             )
 
-        return "jdatetime.datetime(%s, %s, %s, %s, %s)" % (
+        return "jdatetime.datetime({}, {}, {}, {}, {})".format(
             self.year, self.month, self.day, self.hour, self.minute
         )
 
@@ -877,15 +870,11 @@
             c_time.microsecond,
             c_time.tzinfo,
             locale=c_date.locale,
+            fold=c_time.fold,
         )
 
     def timestamp(self):
-        gregorian_datetime = self.togregorian()
-        if timestamp_is_supported:
-            return gregorian_datetime.timestamp()
-        raise NotImplementedError(
-            '`datetime.datetime.timestamp` is not implemented in this version 
of python'
-        )
+        return self.togregorian().timestamp()
 
     @staticmethod
     def fromordinal(ordinal):
@@ -918,13 +907,16 @@
     def tzinfo(self):
         return self.__time.tzinfo
 
+    @property
+    def fold(self):
+        return self._fold
+
     @staticmethod
     def strptime(date_string, format):
         """string, format -> new datetime parsed from a string (like 
time.strptime())"""
-        regex = _directives_to_pattern(_escape(format))
+        regex = _directives_to_pattern(re.escape(format))
 
-        # Cannot use `fullmatch`, it requires Python 3.4+. Use `$` instead.
-        match = _re.match(regex + '$', date_string)
+        match = re.fullmatch(regex, date_string)
         if match is None:
             raise ValueError(
                 "time data '%s' does not match format '%s'" %
@@ -936,14 +928,33 @@
         year = int(get('Y') or get('y') or 1279)
         if year < 100:  # %y, see the discussion at #100
             year += 1400 if year <= 68 else 1300
+        month = get('B') or get('b') or int(get('m', 1))
+        if isinstance(month, str):
+            try:
+                if get('b'):
+                    month = date.j_month_short_to_num(month_name=month)
+                elif month.isascii():
+                    month = date.j_month_to_num(month_name=month)
+                else:
+                    month = date.j_month_fa_to_num(month_name=month)
+            except ValueError:
+                raise ValueError(
+                    "time data '%s' does not match format '%s'" %
+                    (date_string, format)
+                )
+
+        timezone_string = get('z', None)
+        timezone = datetime._timezone_from_string(timezone_string)
+
         return datetime(
             year,
-            int(get('m', 1)),
+            month,
             int(get('d', 1)),
             int(get('H', 0)),
             int(get('M', 0)),
             int(get('S', 0)),
-            None if get('f') is None else int('{0:0<6}'.format(get('f'))),
+            None if get('f') is None else int('{:0<6}'.format(get('f'))),
+            timezone,
         )
 
     def replace(
@@ -956,6 +967,7 @@
         second=None,
         microsecond=None,
         tzinfo=True,
+        fold=None,
     ):
         """Return datetime with new specified fields."""
         t_year = self.year
@@ -989,6 +1001,10 @@
         t_tz = self.tzinfo
         if tzinfo is not True:
             t_tz = tzinfo
+
+        if fold is None:
+            fold = self._fold
+
         return datetime(
             t_year,
             t_month,
@@ -999,6 +1015,7 @@
             t_mic,
             t_tz,
             locale=self.locale,
+            fold=fold,
         )
 
     def __add__(self, timedelta):
@@ -1247,15 +1264,15 @@
         """[sep] -> string in ISO 8601 format,
         YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM]."""
 
-        assert isinstance(sep, _basestring) and len(sep) == 1, \
-            'argument 1 must be a single character: {}'.format(sep)
+        assert isinstance(sep, str) and len(sep) == 1, \
+            f'argument 1 must be a single character: {sep}'
 
         tz = self.strftime("%z")
 
         date_ = self.strftime("%Y-%m-%d")
         time_ = _format_time(self.hour, self.minute, self.second, 
self.microsecond, timespec)
 
-        return '{}{}{}{}'.format(date_, sep, time_, tz)
+        return f'{date_}{sep}{time_}{tz}'
 
     def timetuple(self):
         """Return time tuple, compatible with time.localtime().
@@ -1292,7 +1309,7 @@
         else:
             mil = "." + str(self.microsecond)
         tz = self.strftime("%z")
-        return self.strftime("%Y-%m-%d %H:%M:%S") + "%s%s" % (mil, tz)
+        return self.strftime("%Y-%m-%d %H:%M:%S") + f"{mil}{tz}"
 
     def aslocale(self, locale):
         return datetime(
@@ -1306,3 +1323,29 @@
             tzinfo=self.tzinfo,
             locale=locale,
         )
+
+    @staticmethod
+    def _timezone_from_string(timezone_string):
+        if timezone_string is None:
+            return None
+        z = timezone_string  # keep the original string for value error 
exception.
+        if z[3] == ':':
+            z = z[:3] + z[4:]
+            if len(z) > 5:
+                if z[5] != ':':
+                    msg = f"Inconsistent use of : in {timezone_string}"
+                    raise ValueError(msg)
+                z = z[:5] + z[6:]
+        hours = int(z[1:3])
+        minutes = int(z[3:5])
+        seconds = int(z[5:7] or 0)
+        gmtoff = (hours * 60 * 60) + (minutes * 60) + seconds
+        gmtoff_remainder = z[8:]
+        # Pad to always return microseconds.
+        gmtoff_remainder_padding = "0" * (6 - len(gmtoff_remainder))
+        gmtoff_fraction = int(gmtoff_remainder + gmtoff_remainder_padding)
+        if z.startswith("-"):
+            gmtoff = -gmtoff
+            gmtoff_fraction = -gmtoff_fraction
+        timezone = py_datetime.timezone(timedelta(seconds=gmtoff, 
microseconds=gmtoff_fraction))
+        return timezone
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/setup.py 
new/python-jalali-4.1.0/setup.py
--- old/python-jalali-3.8.2/setup.py    2022-01-24 20:05:29.000000000 +0100
+++ new/python-jalali-4.1.0/setup.py    2022-03-22 15:07:54.000000000 +0100
@@ -4,7 +4,7 @@
 
 setup(
     name='jdatetime',
-    version='3.8.2',
+    version='4.1.0',
     packages=['jdatetime', ],
     license='Python Software Foundation License',
     keywords='Jalali implementation of Python datetime',
@@ -14,19 +14,12 @@
     description=("Jalali datetime binding for python"),
     url="https://github.com/slashmili/python-jalali";,
     long_description=open('README').read(),
+    python_requires=">=3.7",
     classifiers=[
         "Intended Audience :: Developers",
         "Intended Audience :: System Administrators",
         "Operating System :: OS Independent",
         "Programming Language :: Python",
-        "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 2.6",
-        "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.2",
-        "Programming Language :: Python :: 3.4",
-        "Programming Language :: Python :: 3.5",
-        "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/tests/test_jdate.py 
new/python-jalali-4.1.0/tests/test_jdate.py
--- old/python-jalali-3.8.2/tests/test_jdate.py 2022-01-24 20:05:29.000000000 
+0100
+++ new/python-jalali-4.1.0/tests/test_jdate.py 2022-03-22 15:07:54.000000000 
+0100
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 import datetime
 import pickle
 import sys
@@ -46,7 +45,7 @@
 
     def test_init_accepts_instance_locale(self):
         date = jdatetime.date(1397, 4, 23, locale=jdatetime.FA_LOCALE)
-        self.assertEqual(date.strftime('%A'), u'????????')
+        self.assertEqual(date.strftime('%A'), '????????')
 
     def test_dates_are_not_equal_if_locales_are_different(self):
         date_fa = jdatetime.date(1397, 4, 22, locale='fa_IR')
@@ -137,4 +136,4 @@
 
         with open('tests/pickled_objects/%s' % pickled_object_file, 'rb') as f:
             d = pickle.load(f)
-        assert d == jdatetime.date(1400, 10, 11)
+        self.assertEqual(d, jdatetime.date(1400, 10, 11))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/tests/test_jdatetime.py 
new/python-jalali-4.1.0/tests/test_jdatetime.py
--- old/python-jalali-3.8.2/tests/test_jdatetime.py     2022-01-24 
20:05:29.000000000 +0100
+++ new/python-jalali-4.1.0/tests/test_jdatetime.py     2022-03-22 
15:07:54.000000000 +0100
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 import datetime
 import locale
 import pickle
@@ -69,6 +68,37 @@
         with self.assertRaises(AttributeError):
             datetime.locale = jdatetime.FA_LOCALE
 
+    def test_fold(self):
+        # Test default value
+        dt = jdatetime.datetime(1400, 11, 22)
+        self.assertEqual(dt.fold, 0)
+        self.assertEqual(dt.time().fold, 0)
+
+        # Test custome value for fold
+        dt = jdatetime.datetime(1400, 11, 22, fold=1)
+        self.assertEqual(dt.fold, 1)
+        self.assertEqual(dt.time().fold, 1)
+
+        # Test invalid value for fold
+        with self.assertRaises(
+            ValueError,
+            msg='fold must be either 0 or 1'
+        ):
+            jdatetime.datetime(1400, 11, 22, fold=2)
+
+        # Test combine
+        t = jdatetime.time(12, 13, 14, fold=1)
+        d = jdatetime.date(1400, 11, 22)
+        self.assertEqual(
+            jdatetime.datetime.combine(d, t),
+            jdatetime.datetime(1400, 11, 22, 12, 13, 14, fold=1),
+        )
+
+        # Test replace
+        dt = jdatetime.datetime(1400, 11, 22, fold=0)
+        new_dt = dt.replace(fold=1)
+        self.assertEqual(new_dt.fold, 1)
+
     def test_locale_property_returns_locale(self):
         datetime = jdatetime.datetime(1397, 4, 22, locale='nl_NL')
         self.assertEqual(datetime.locale, 'nl_NL')
@@ -79,7 +109,7 @@
 
     def test_init_accepts_instance_locale(self):
         datetime = jdatetime.datetime(1397, 4, 23, locale=jdatetime.FA_LOCALE)
-        self.assertEqual(datetime.strftime('%A'), u'????????')
+        self.assertEqual(datetime.strftime('%A'), '????????')
 
     def test_today(self):
         today = datetime.date.today()
@@ -98,22 +128,22 @@
 
     def test_comparison(self):
         today = jdatetime.date.today()
-        self.assertEqual(False, today < today - jdatetime.timedelta(days=76))
-        self.assertEqual(False, today <= today - jdatetime.timedelta(days=1))
-        self.assertEqual(True, today + jdatetime.timedelta(days=1) > today)
-        self.assertEqual(True, today + jdatetime.timedelta(days=30) >= today)
-        self.assertEqual(True, today == today)
-        self.assertEqual(False, today > today)
-        self.assertEqual(False, today < today)
-        self.assertEqual(True, today >= today)
-        self.assertEqual(True, today <= today)
+        self.assertFalse(today < today - jdatetime.timedelta(days=76))
+        self.assertFalse(today <= today - jdatetime.timedelta(days=1))
+        self.assertTrue(today + jdatetime.timedelta(days=1) > today)
+        self.assertTrue(today + jdatetime.timedelta(days=30) >= today)
+        self.assertTrue(today == today)
+        self.assertFalse(today > today)
+        self.assertFalse(today < today)
+        self.assertTrue(today >= today)
+        self.assertTrue(today <= today)
         not_today = jdatetime.date(today.year, today.month, today.day) + 
jdatetime.timedelta(days=1)
-        self.assertEqual(True, today != not_today)
+        self.assertTrue(today != not_today)
 
         dtg = jdatetime.datetime(1380, 12, 1, 1, 2, 4)
-        self.assertEqual(True, dtg < dtg + jdatetime.timedelta(seconds=1))
-        self.assertEqual(True, dtg - jdatetime.timedelta(seconds=1) < dtg)
-        self.assertEqual(False, dtg is None)
+        self.assertTrue(dtg < dtg + jdatetime.timedelta(seconds=1))
+        self.assertTrue(dtg - jdatetime.timedelta(seconds=1) < dtg)
+        self.assertFalse(dtg is None)
 
     def test_date_conversion_date_input(self):
         # todo: add some corner cases
@@ -143,7 +173,7 @@
         )
 
         gdatetime = datetime.datetime(2011, 5, 13, 14, 15, 16)
-        self.assertEqual(True, jd_datetime.togregorian() == gdatetime)
+        self.assertEqual(jd_datetime.togregorian(), gdatetime)
 
     def test_strftime(self):
         s = jdatetime.date(1390, 2, 23)
@@ -163,8 +193,8 @@
         self.assertEqual(dt.strftime(unicode_format), output)
 
         dt = jdatetime.datetime(1390, 2, 23, 12, 13, 14, 1)
-        string_format = u"????????? = %y?? ????????? = %m?? ????????? = %d"
-        output = u"????????? = 90?? ????????? = 02?? ????????? = 23"
+        string_format = "????????? = %y?? ????????? = %m?? ????????? = %d"
+        output = "????????? = 90?? ????????? = 02?? ????????? = 23"
         self.assertEqual(dt.strftime(string_format), output)
 
         class NYCTime(jdatetime.tzinfo):
@@ -179,15 +209,15 @@
 
         nyc = NYCTime()
         dt = jdatetime.datetime(1389, 2, 17, 19, 10, 2, tzinfo=nyc)
-        self.assertEqual(True, dt.strftime("%Z %z") == "EDT -0400")
+        self.assertEqual(dt.strftime("%Z %z"), "EDT -0400")
 
         teh = TehranTime()
         dt = jdatetime.datetime(1389, 2, 17, 19, 10, 2, tzinfo=teh)
-        self.assertEqual(True, dt.strftime("%Z %z") == "IRDT +0330")
+        self.assertEqual(dt.strftime("%Z %z"), "IRDT +0330")
 
     def test_strftime_unicode(self):
         s = jdatetime.date(1390, 2, 23)
-        self.assertEqual(s.strftime("%a %A".encode("utf-8")), "Fri Friday")
+        self.assertEqual(s.strftime(b"%a %A"), "Fri Friday")
 
     def test_strftime_single_digit(self):
         dt = jdatetime.datetime(1390, 2, 3, 4, 5, 6)
@@ -198,13 +228,13 @@
 
     def test_kabiseh(self):
         kabiseh_year = jdatetime.date.fromgregorian(date=datetime.date(2013, 
3, 20))
-        self.assertEqual(True, kabiseh_year.isleap() is True)
+        self.assertTrue(kabiseh_year.isleap())
 
         normal_year = jdatetime.date.fromgregorian(date=datetime.date(2014, 3, 
20))
-        self.assertEqual(True, normal_year.isleap() is False)
+        self.assertFalse(normal_year.isleap())
 
         kabiseh_year = jdatetime.date(1391, 12, 30)
-        self.assertEqual(True, kabiseh_year.isleap() is True)
+        self.assertTrue(kabiseh_year.isleap())
 
         with self.assertRaises(ValueError):
             jdatetime.date(1392, 12, 30)
@@ -212,29 +242,29 @@
     def test_datetime(self):
         d = jdatetime.datetime(1390, 1, 2, 12, 13, 14)
 
-        self.assertEqual(True, d.time() == jdatetime.time(12, 13, 14))
-        self.assertEqual(True, d.date() == jdatetime.date(1390, 1, 2))
+        self.assertEqual(d.time(), jdatetime.time(12, 13, 14))
+        self.assertEqual(d.date(), jdatetime.date(1390, 1, 2))
 
     def test_datetimetoday(self):
         jnow = jdatetime.datetime.today()
         today = datetime.datetime.today().date()
         gnow = jdatetime.date.fromgregorian(date=today)
 
-        self.assertEqual(True, jnow.date() == gnow)
+        self.assertEqual(jnow.date(), gnow)
 
     def test_datetimefromtimestamp(self):
         t = time.time()
         jnow = jdatetime.datetime.fromtimestamp(t).date()
         gnow = datetime.datetime.fromtimestamp(t).date()
 
-        self.assertEqual(True, jdatetime.date.fromgregorian(date=gnow) == jnow)
+        self.assertEqual(jdatetime.date.fromgregorian(date=gnow), jnow)
 
     def test_combine(self):
         t = jdatetime.time(12, 13, 14)
         d = jdatetime.date(1390, 4, 5)
         dt = jdatetime.datetime(1390, 4, 5, 12, 13, 14)
 
-        self.assertEqual(True, jdatetime.datetime.combine(d, t) == dt)
+        self.assertEqual(jdatetime.datetime.combine(d, t), dt)
 
     def test_combine_keeps_date_locale(self):
         t = jdatetime.time(11, 20, 30)
@@ -255,7 +285,7 @@
         dtr = dt.replace(**args)
         dtn = jdatetime.datetime(1390, 12, 1, 13, 14, 15, 1233)
 
-        self.assertEqual(True, dtr == dtn)
+        self.assertEqual(dtr, dtn)
 
     def test_replace_keeps_date_locale(self):
         dt = jdatetime.datetime(1397, 4, 24, locale='nl_NL')
@@ -274,7 +304,7 @@
         dt1 = jdatetime.datetime.strptime(date_string, date_format)
         dt2 = jdatetime.datetime(1363, 6, 6, 12, 13, 14)
 
-        self.assertEqual(True, dt1 == dt2)
+        self.assertEqual(dt1, dt2)
 
     def test_strptime_bare(self):
         date_string = "13630606121314"
@@ -327,6 +357,75 @@
             jdatetime.datetime.strptime("0123", "%f")
         )
 
+    def test_strptime_handle_b_B_directive(self):
+        tests = [
+            ('14 Ordibehesht 1400', '%d %B %Y'),
+            ('14 ordibehesht 1400', '%d %B %Y'),
+            ('14 ordiBehesHt 1400', '%d %B %Y'),
+            ('???? Ordibehesht ????????', '%d %B %Y'),
+            ('???? ordibehesht ????????', '%d %B %Y'),
+            ('???? orDibeHesht ????????', '%d %B %Y'),
+            ('1?? Ordibehesht 14????', '%d %B %Y'),
+            ('??4 ordibehesht 14??0', '%d %B %Y'),
+            ('??4 OrdiBeheshT 14??0', '%d %B %Y'),
+            ('???? ???????????????? ????????', '%d %B %Y'),
+            ('14 ???????????????? 1400', '%d %B %Y'),
+            ('1?? ???????????????? ??4??0', '%d %B %Y'),
+            ('14 Ord 1400', '%d %b %Y'),
+            ('14 ord 1400', '%d %b %Y'),
+            ('14 oRD 1400', '%d %b %Y'),
+            ('???? Ord ????????', '%d %b %Y'),
+            ('???? ord ????????', '%d %b %Y'),
+            ('???? OrD ????????', '%d %b %Y'),
+            ('??4 Ord 14??0', '%d %b %Y'),
+            ('??4 ord 14??0', '%d %b %Y'),
+            ('??4 ORD 14??0', '%d %b %Y'),
+        ]
+        for date_string, date_format in tests:
+            with self.subTest(date_string=date_string, 
date_format=date_format):
+                date = jdatetime.datetime.strptime(date_string, date_format)
+                self.assertEqual(jdatetime.datetime(1400, 2, 14), date)
+
+    def test_strptime_invalid_date_string_b_directive(self):
+        with self.assertRaises(ValueError, msg="time data '14 DRO 1400' does 
not match format '%d %b %Y'"):
+            jdatetime.datetime.strptime('14 DRO 1400', '%d %b %Y')
+
+    def test_strptime_invalid_date_string_B_directive(self):
+        with self.assertRaises(ValueError, msg="time data '14 ordi 1400' does 
not match format '%d %B %Y'"):
+            jdatetime.datetime.strptime('14 ordi 1400', '%d %B %Y')
+
+    def test_strptime_handle_z_directive(self):
+        tests = [
+            ('+0123', '%z', datetime.timedelta(seconds=4980)),
+            ('-0123', '%z', datetime.timedelta(seconds=-4980)),
+            ('+????????', '%z', datetime.timedelta(seconds=4980)),
+            ('-??????3', '%z', datetime.timedelta(seconds=-4980)),
+            ('+012345', '%z', datetime.timedelta(seconds=5025)),
+            ('+012345.012345', '%z', datetime.timedelta(seconds=5025, 
microseconds=12345)),
+            ('-012345.012345', '%z', datetime.timedelta(seconds=-5025, 
microseconds=-12345)),
+            ('+01:23', '%z', datetime.timedelta(seconds=4980)),
+            ('+01:23:45', '%z', datetime.timedelta(seconds=5025)),
+            ('+01:23:45.123', '%z', datetime.timedelta(seconds=5025, 
microseconds=123000))
+        ]
+        for date_string, date_format, time_delta in tests:
+            with self.subTest(date_string=date_string, 
date_format=date_format):
+                date = jdatetime.datetime.strptime(date_string, date_format)
+                self.assertEqual(datetime.timezone(time_delta), date.tzinfo)
+
+    def test_strptime_invalid_date_string_z_directive(self):
+        tests = [
+            ('0123', '%z', "time data '0123' does not match format '%z'"),
+            ('-01', '%z', "time data '-01' does not match format '%z'"),
+            ('+012', '%z', "time data '+012' does not match format '%z'"),
+            ('+01:2356', '%z', "Inconsistent use of : in -01:2356"),
+            ('+0123:56', '%z', "invalid literal for int() with base 10: ':5'"),
+            ('+012345123456', '%z', "time data '+012345123456' does not match 
format '%z'"),
+        ]
+        for date_string, date_format, msg in tests:
+            with self.subTest(date_string=date_string, 
date_format=date_format, msg=msg):
+                with self.assertRaises(ValueError, msg=msg):
+                    jdatetime.datetime.strptime(date_string, date_format)
+
     def test_datetime_eq(self):
         date_string = "1363-6-6 12:13:14"
         date_format = "%Y-%m-%d %H:%M:%S"
@@ -336,14 +435,14 @@
         date_string = "1364-6-6 12:13:14"
         dt2 = jdatetime.datetime.strptime(date_string, date_format)
 
-        self.assertEqual(False, dt2 == dt1)
+        self.assertNotEqual(dt2, dt1)
 
     def test_datetime_eq_now(self):
         import time
         dt1 = jdatetime.datetime.now()
         time.sleep(0.1)
         dt2 = jdatetime.datetime.now()
-        self.assertEqual(False, dt2 == dt1)
+        self.assertNotEqual(dt2, dt1)
 
     def test_timetz(self):
         teh = TehranTime()
@@ -357,13 +456,13 @@
 
         dt_gmt = datetime.datetime(2015, 6, 27, 0, 0, 0, tzinfo=gmt)
         dt_teh = datetime.datetime(2015, 6, 27, 3, 30, 0, tzinfo=teh)
-        self.assertEqual(True, dt_teh == dt_gmt, "In standrd python datetime, 
__eq__ considers timezone")
+        self.assertEqual(dt_teh, dt_gmt, "In standrd python datetime, __eq__ 
considers timezone")
 
         jdt_gmt = jdatetime.datetime(1389, 2, 17, 0, 0, 0, tzinfo=gmt)
 
         jdt_teh = jdatetime.datetime(1389, 2, 17, 3, 30, 0, tzinfo=teh)
 
-        self.assertEqual(True, jdt_teh == jdt_gmt)
+        self.assertEqual(jdt_teh, jdt_gmt)
 
     def test_datetimes_with_different_locales_are_not_equal(self):
         dt_en = jdatetime.datetime(2018, 4, 15, 0, 0, 0, locale='en_US')
@@ -532,7 +631,7 @@
         self.set_fa_locale()
         day_of_week = jdatetime.date(1395, 1, 2).strftime("%a")
 
-        self.assertEqual(day_of_week, u"????????????")
+        self.assertEqual(day_of_week, "????????????")
 
     def set_fa_locale(self):
         if platform.system() == 'Windows':
@@ -610,7 +709,7 @@
         jiso = jdt.isoformat('M')
         # Used to raise:
         # AssertionError: argument 1 must be a single character: M
-        ujiso = jdt.isoformat(u'M')
+        ujiso = jdt.isoformat('M')
         self.assertEqual(jiso, ujiso)
 
     def test_isoformat_bad_sep(self):
@@ -653,7 +752,7 @@
 
         with open('tests/pickled_objects/%s' % pickled_object_file, 'rb') as f:
             dt = pickle.load(f)
-        assert dt == jdatetime.datetime(1400, 10, 11, 1, 2, 3, 30)
+        self.assertEqual(dt, jdatetime.datetime(1400, 10, 11, 1, 2, 3, 30))
 
 
 class TestJdatetimeGetSetLocale(TestCase):
@@ -732,7 +831,7 @@
         fa_th.start()
         fa_th.join()
 
-        self.assertEqual([u'????????????', u'??????????'], fa_record)
+        self.assertEqual(['???????????????', '??????????'], fa_record)
 
     @skipUnless(greenlet_installed, 'greenlets ident is used when greenlet 
module is installed')
     def 
test_set_locale_sets_default_locale_for_date_objects_with_greenlets(self):
@@ -746,4 +845,4 @@
         fa_greenlet = greenlet.greenlet(record_locale_formatted_date)
         fa_greenlet.switch(fa_record, jdatetime.FA_LOCALE)
 
-        self.assertEqual([u'????????????', u'??????????'], fa_record)
+        self.assertEqual(['???????????????', '??????????'], fa_record)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-jalali-3.8.2/tox.ini 
new/python-jalali-4.1.0/tox.ini
--- old/python-jalali-3.8.2/tox.ini     2022-01-24 20:05:29.000000000 +0100
+++ new/python-jalali-4.1.0/tox.ini     2022-03-22 15:07:54.000000000 +0100
@@ -1,13 +1,11 @@
 [tox]
 envlist =
-    py{27,32,34,35,36,37,38,39,310}
+    py{37,38,39,310}
     flake8
+    isort
 
 [gh-actions]
 python =
-    2.7: py27
-    3.5: py35
-    3.6: py36
     3.7: py37
     3.8: py38
     3.9: py39

Reply via email to