Hello community, here is the log from the commit of package python-isodate for openSUSE:Factory checked in at 2018-05-04 11:26:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-isodate (Old) and /work/SRC/openSUSE:Factory/.python-isodate.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-isodate" Fri May 4 11:26:07 2018 rev:14 rq:603117 version:0.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-isodate/python-isodate.changes 2017-05-16 14:29:51.132130506 +0200 +++ /work/SRC/openSUSE:Factory/.python-isodate.new/python-isodate.changes 2018-05-04 11:26:12.607006999 +0200 @@ -1,0 +2,8 @@ +Wed May 2 12:53:11 UTC 2018 - adrian.glaub...@suse.com + +- update to version 0.6.0: + - Support incomplete month date (Fabien Loffredo) + - Rely on duck typing when doing duration maths + - Support ':' as separator in fractional time zones (usrenmae) + +------------------------------------------------------------------- Old: ---- isodate-0.5.4.tar.gz New: ---- isodate-0.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-isodate.spec ++++++ --- /var/tmp/diff_new_pack.X9FZrU/_old 2018-05-04 11:26:13.134987632 +0200 +++ /var/tmp/diff_new_pack.X9FZrU/_new 2018-05-04 11:26:13.138987485 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-isodate # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -15,12 +15,13 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # + # Tests don't work and cause a dependency loop with python-SPARQLWrapper %bcond_without tests %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-isodate -Version: 0.5.4 +Version: 0.6.0 Release: 0 Url: http://cheeseshop.python.org/pypi/isodate Summary: An ISO 8601 Date/Time/Duration Parser and Formatter @@ -28,10 +29,10 @@ Group: Development/Languages/Python Source: https://files.pythonhosted.org/packages/source/i/isodate/isodate-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build -BuildRequires: fdupes -BuildRequires: python-rpm-macros BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} +BuildRequires: fdupes +BuildRequires: python-rpm-macros BuildArch: noarch %python_subpackages ++++++ isodate-0.5.4.tar.gz -> isodate-0.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/CHANGES.txt new/isodate-0.6.0/CHANGES.txt --- old/isodate-0.5.4/CHANGES.txt 2015-08-06 00:56:24.000000000 +0200 +++ new/isodate-0.6.0/CHANGES.txt 2017-10-13 06:33:18.000000000 +0200 @@ -2,6 +2,14 @@ CHANGES ======= +0.6.0 (2017-10-13) +------------------ + +- support incomplete month date (Fabien Loffredo) +- rely on duck typing when doing duration maths +- support ':' as separator in fractional time zones (usrenmae) + + 0.5.4 (2015-08-06) ------------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/PKG-INFO new/isodate-0.6.0/PKG-INFO --- old/isodate-0.5.4/PKG-INFO 2015-08-06 00:56:38.000000000 +0200 +++ new/isodate-0.6.0/PKG-INFO 2017-10-13 11:25:07.000000000 +0200 @@ -1,8 +1,8 @@ Metadata-Version: 1.1 Name: isodate -Version: 0.5.4 +Version: 0.6.0 Summary: An ISO 8601 date/time/duration parser and formatter -Home-page: http://cheeseshop.python.org/pypi/isodate +Home-page: https://github.com/gweis/isodate/ Author: Gerhard Weis Author-email: gerhard.w...@proclos.com License: BSD @@ -16,14 +16,11 @@ .. image:: https://coveralls.io/repos/gweis/isodate/badge.svg?branch=master :target: https://coveralls.io/r/gweis/isodate?branch=master :alt: Coveralls - .. image:: https://pypip.in/version/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ + .. image:: https://img.shields.io/pypi/v/isodate.svg + :target: https://pypi.python.org/pypi/isodate/ :alt: Latest Version - .. image:: https://pypip.in/download/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ - :alt: Downloads - .. image:: https://pypip.in/license/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ + .. image:: https://img.shields.io/pypi/l/isodate.svg + :target: https://pypi.python.org/pypi/isodate/ :alt: License @@ -121,14 +118,22 @@ The doc strings and unit tests should provide rather detailed information about the methods and their limitations. - The source release provides a *setup.py* script and a *buildout.cfg*. Both can - be used to run the unit tests included. + The source release provides a *setup.py* script, + which can be used to run the unit tests included. Source code is available at `<http://github.com/gweis/isodate>`_. CHANGES ======= + 0.6.0 (2017-10-13) + ------------------ + + - support incomplete month date (Fabien Loffredo) + - rely on duck typing when doing duration maths + - support ':' as separator in fractional time zones (usrenmae) + + 0.5.4 (2015-08-06) ------------------ @@ -265,9 +270,10 @@ Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet Classifier: Topic :: Software Development :: Libraries :: Python Modules diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/README.rst new/isodate-0.6.0/README.rst --- old/isodate-0.5.4/README.rst 2015-05-18 20:27:00.000000000 +0200 +++ new/isodate-0.6.0/README.rst 2017-10-13 06:24:48.000000000 +0200 @@ -8,14 +8,11 @@ .. image:: https://coveralls.io/repos/gweis/isodate/badge.svg?branch=master :target: https://coveralls.io/r/gweis/isodate?branch=master :alt: Coveralls -.. image:: https://pypip.in/version/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ +.. image:: https://img.shields.io/pypi/v/isodate.svg + :target: https://pypi.python.org/pypi/isodate/ :alt: Latest Version -.. image:: https://pypip.in/download/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ - :alt: Downloads -.. image:: https://pypip.in/license/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ +.. image:: https://img.shields.io/pypi/l/isodate.svg + :target: https://pypi.python.org/pypi/isodate/ :alt: License @@ -113,7 +110,7 @@ The doc strings and unit tests should provide rather detailed information about the methods and their limitations. -The source release provides a *setup.py* script and a *buildout.cfg*. Both can -be used to run the unit tests included. +The source release provides a *setup.py* script, +which can be used to run the unit tests included. Source code is available at `<http://github.com/gweis/isodate>`_. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/setup.cfg new/isodate-0.6.0/setup.cfg --- old/isodate-0.5.4/setup.cfg 2015-08-06 00:56:38.000000000 +0200 +++ new/isodate-0.6.0/setup.cfg 2017-10-13 11:25:07.000000000 +0200 @@ -1,5 +1,7 @@ +[bdist_wheel] +universal = 1 + [egg_info] tag_build = -tag_svn_revision = 0 tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/setup.py new/isodate-0.6.0/setup.py --- old/isodate-0.5.4/setup.py 2015-08-06 00:56:15.000000000 +0200 +++ new/isodate-0.6.0/setup.py 2017-10-13 06:33:54.000000000 +0200 @@ -26,32 +26,22 @@ # CONTRACT, STRICT LIABILITY, OR TORT ############################################################################## import os -import sys - -setupargs = {} - -try: - from setuptools import setup - setupargs['test_suite'] = 'isodate.tests.test_suite' - if sys.version[0] == '3': - setupargs['use_2to3'] = True -except ImportError: - from distutils.core import setup - if sys.version[0] == '3': - from distutils.command.build_py import build_py_2to3 - setupargs['cmdclass'] = {'build_py': build_py_2to3} +from setuptools import setup def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() + setup(name='isodate', - version='0.5.4', + version='0.6.0', packages=['isodate', 'isodate.tests'], package_dir={'': 'src'}, # dependencies: - # install_requires = [], + install_requires=[ + 'six' + ], # PyPI metadata author='Gerhard Weis', @@ -59,7 +49,7 @@ description='An ISO 8601 date/time/duration parser and formatter', license='BSD', # keywords = '', - url='http://cheeseshop.python.org/pypi/isodate', + url='https://github.com/gweis/isodate/', long_description=(read('README.rst') + read('CHANGES.txt') + @@ -73,12 +63,13 @@ 'Programming Language :: Python', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Internet', ('Topic :: Software Development :' ': Libraries :: Python Modules'), ], - **setupargs) + test_suite='isodate.tests.test_suite') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/__init__.py new/isodate-0.6.0/src/isodate/__init__.py --- old/isodate-0.5.4/src/isodate/__init__.py 2015-04-01 06:44:00.000000000 +0200 +++ new/isodate-0.6.0/src/isodate/__init__.py 2017-07-06 03:59:29.000000000 +0200 @@ -43,7 +43,8 @@ from isodate.isostrf import DATE_BAS_WEEK, DATE_BAS_WEEK_COMPLETE from isodate.isostrf import DATE_CENTURY, DATE_EXT_COMPLETE from isodate.isostrf import DATE_EXT_ORD_COMPLETE, DATE_EXT_WEEK -from isodate.isostrf import DATE_EXT_WEEK_COMPLETE, DATE_MONTH, DATE_YEAR +from isodate.isostrf import DATE_EXT_WEEK_COMPLETE, DATE_YEAR +from isodate.isostrf import DATE_BAS_MONTH, DATE_EXT_MONTH from isodate.isostrf import TIME_BAS_COMPLETE, TIME_BAS_MINUTE from isodate.isostrf import TIME_EXT_COMPLETE, TIME_EXT_MINUTE from isodate.isostrf import TIME_HOUR @@ -61,7 +62,8 @@ 'strftime', 'DATE_BAS_COMPLETE', 'DATE_BAS_ORD_COMPLETE', 'DATE_BAS_WEEK', 'DATE_BAS_WEEK_COMPLETE', 'DATE_CENTURY', 'DATE_EXT_COMPLETE', 'DATE_EXT_ORD_COMPLETE', 'DATE_EXT_WEEK', - 'DATE_EXT_WEEK_COMPLETE', 'DATE_MONTH', 'DATE_YEAR', + 'DATE_EXT_WEEK_COMPLETE', 'DATE_YEAR', + 'DATE_BAS_MONTH', 'DATE_EXT_MONTH', 'TIME_BAS_COMPLETE', 'TIME_BAS_MINUTE', 'TIME_EXT_COMPLETE', 'TIME_EXT_MINUTE', 'TIME_HOUR', 'TZ_BAS', 'TZ_EXT', 'TZ_HOUR', 'DT_BAS_COMPLETE', 'DT_EXT_COMPLETE', 'DT_BAS_ORD_COMPLETE', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/duration.py new/isodate-0.6.0/src/isodate/duration.py --- old/isodate-0.5.4/src/isodate/duration.py 2015-08-06 00:34:35.000000000 +0200 +++ new/isodate-0.6.0/src/isodate/duration.py 2017-10-13 06:25:59.000000000 +0200 @@ -30,7 +30,7 @@ The class Duration allows to define durations in years and months and can be used as limited replacement for timedelta objects. ''' -from datetime import date, datetime, timedelta +from datetime import timedelta from decimal import Decimal, ROUND_FLOOR @@ -121,7 +121,10 @@ if self.years: params.append('%d years' % self.years) if self.months: - params.append('%d months' % self.months) + fmt = "%d months" + if self.months <= 1: + fmt = "%d month" + params.append(fmt % self.months) params.append(str(self.tdelta)) return ', '.join(params) @@ -156,16 +159,15 @@ Durations can be added with Duration, timedelta, date and datetime objects. ''' - if isinstance(other, timedelta): - newduration = Duration(years=self.years, months=self.months) - newduration.tdelta = self.tdelta + other - return newduration if isinstance(other, Duration): newduration = Duration(years=self.years + other.years, months=self.months + other.months) newduration.tdelta = self.tdelta + other.tdelta return newduration - if isinstance(other, (date, datetime)): + try: + # try anything that looks like a date or datetime + # 'other' has attributes year, month, day + # and relies on 'timedelta + other' being implemented if (not(float(self.years).is_integer() and float(self.months).is_integer())): raise ValueError('fractional years or months not supported' @@ -179,35 +181,24 @@ else: newday = other.day newdt = other.replace(year=newyear, month=newmonth, day=newday) + # does a timedelta + date/datetime return self.tdelta + newdt - raise TypeError('unsupported operand type(s) for +: %s and %s' % - (self.__class__, other.__class__)) - - def __radd__(self, other): - ''' - Add durations to timedelta, date and datetime objects. - ''' - if isinstance(other, timedelta): + except AttributeError: + # other probably was not a date/datetime compatible object + pass + try: + # try if other is a timedelta + # relies on timedelta + timedelta supported newduration = Duration(years=self.years, months=self.months) newduration.tdelta = self.tdelta + other return newduration - if isinstance(other, (date, datetime)): - if (not(float(self.years).is_integer() and - float(self.months).is_integer())): - raise ValueError('fractional years or months not supported' - ' for date calculations') - newmonth = other.month + self.months - carry, newmonth = fquotmod(newmonth, 1, 13) - newyear = other.year + self.years + carry - maxdays = max_days_in_month(newyear, newmonth) - if other.day > maxdays: - newday = maxdays - else: - newday = other.day - newdt = other.replace(year=newyear, month=newmonth, day=newday) - return newdt + self.tdelta - raise TypeError('unsupported operand type(s) for +: %s and %s' % - (other.__class__, self.__class__)) + except AttributeError: + # ignore ... other probably was not a timedelta compatible object + pass + # we have tried everything .... return a NotImplemented + return NotImplemented + + __radd__ = __add__ def __mul__(self, other): if isinstance(other, int): @@ -216,19 +207,9 @@ months=self.months * other) newduration.tdelta = self.tdelta * other return newduration - raise TypeError('unsupported operand type(s) for +: %s and %s' % - (self.__class__, other.__class__)) + return NotImplemented - def __rmul__(self, other): - - if isinstance(other, int): - newduration = Duration( - years=self.years * other, - months=self.months * other) - newduration.tdelta = self.tdelta * other - return newduration - raise TypeError('unsupported operand type(s) for +: %s and %s' % - (other.__class__, self.__class__)) + __rmul__ = __mul__ def __sub__(self, other): ''' @@ -240,20 +221,37 @@ months=self.months - other.months) newduration.tdelta = self.tdelta - other.tdelta return newduration - if isinstance(other, timedelta): + try: + # do maths with our timedelta object .... newduration = Duration(years=self.years, months=self.months) newduration.tdelta = self.tdelta - other return newduration - raise TypeError('unsupported operand type(s) for -: %s and %s' % - (self.__class__, other.__class__)) + except TypeError: + # looks like timedelta - other is not implemented + pass + return NotImplemented def __rsub__(self, other): ''' It is possible to subtract Duration objecs from date, datetime and timedelta objects. + + TODO: there is some weird behaviour in date - timedelta ... + if timedelta has seconds or microseconds set, then + date - timedelta != date + (-timedelta) + for now we follow this behaviour to avoid surprises when mixing + timedeltas with Durations, but in case this ever changes in + the stdlib we can just do: + return -self + other + instead of all the current code ''' - # print '__rsub__:', self, other - if isinstance(other, (date, datetime)): + if isinstance(other, timedelta): + tmpdur = Duration() + tmpdur.tdelta = other + return tmpdur - self + try: + # check if other behaves like a date/datetime object + # does it have year, month, day and replace? if (not(float(self.years).is_integer() and float(self.months).is_integer())): raise ValueError('fractional years or months not supported' @@ -268,27 +266,26 @@ newday = other.day newdt = other.replace(year=newyear, month=newmonth, day=newday) return newdt - self.tdelta - if isinstance(other, timedelta): - tmpdur = Duration() - tmpdur.tdelta = other - return tmpdur - self - raise TypeError('unsupported operand type(s) for -: %s and %s' % - (other.__class__, self.__class__)) + except AttributeError: + # other probably was not compatible with data/datetime + pass + return NotImplemented def __eq__(self, other): ''' If the years, month part and the timedelta part are both equal, then the two Durations are considered equal. ''' - if ((isinstance(other, timedelta) and - self.years == 0 and self.months == 0)): + if isinstance(other, Duration): + if (((self.years * 12 + self.months) == + (other.years * 12 + other.months) and + self.tdelta == other.tdelta)): + return True + return False + # check if other con be compared against timedelta object + # will raise an AssertionError when optimisation is off + if self.years == 0 and self.months == 0: return self.tdelta == other - if not isinstance(other, Duration): - return NotImplemented - if (((self.years * 12 + self.months) == - (other.years * 12 + other.months) and - self.tdelta == other.tdelta)): - return True return False def __ne__(self, other): @@ -296,17 +293,17 @@ If the years, month part or the timedelta part is not equal, then the two Durations are considered not equal. ''' - if ((isinstance(other, timedelta) and - self.years == 0 and - self.months == 0)): + if isinstance(other, Duration): + if (((self.years * 12 + self.months) != + (other.years * 12 + other.months) or + self.tdelta != other.tdelta)): + return True + return False + # check if other can be compared against timedelta object + # will raise an AssertionError when optimisation is off + if self.years == 0 and self.months == 0: return self.tdelta != other - if not isinstance(other, Duration): - return NotImplemented - if (((self.years * 12 + self.months) != - (other.years * 12 + other.months) or - self.tdelta != other.tdelta)): - return True - return False + return True def totimedelta(self, start=None, end=None): ''' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/isodates.py new/isodate-0.6.0/src/isodate/isodates.py --- old/isodate-0.5.4/src/isodate/isodates.py 2014-11-06 19:27:25.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/isodates.py 2017-07-06 03:59:29.000000000 +0200 @@ -108,6 +108,10 @@ cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})" r"-(?P<month>[0-9]{2})" % (sign, yeardigits))) + # YYYMM or +-YYYYYYMM ... basic incomplete month date format + cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})" + r"(?P<month>[0-9]{2})" + % (sign, yeardigits))) # 6. year dates: # YYYY or +-YYYYYY ... reduced accuracy specific year cache_entry.append(re.compile(r"(?P<sign>[+-]){%d}(?P<year>[0-9]{%d})" @@ -122,7 +126,9 @@ return DATE_REGEX_CACHE[(yeardigits, expanded)] -def parse_date(datestring, yeardigits=4, expanded=False): +def parse_date( + datestring, + yeardigits=4, expanded=False, defaultmonth=1, defaultday=1): ''' Parse an ISO 8601 date string into a datetime.date object. @@ -143,6 +149,7 @@ YYYY-DDD +-YYYYYY-DDD extended ordinal date YYYYWww +-YYYYYYWww basic incomplete week date YYYY-Www +-YYYYYY-Www extended incomplete week date + YYYMM +-YYYYYYMM basic incomplete month date YYY-MM +-YYYYYY-MM incomplete month date YYYY +-YYYYYY incomplete year date YY +-YYYY incomplete century date @@ -167,7 +174,9 @@ # FIXME: negative dates not possible with python standard types sign = (groups['sign'] == '-' and -1) or 1 if 'century' in groups: - return date(sign * (int(groups['century']) * 100 + 1), 1, 1) + return date( + sign * (int(groups['century']) * 100 + 1), + defaultmonth, defaultday) if 'month' not in groups: # weekdate or ordinal date ret = date(sign * int(groups['year']), 1, 1) if 'week' in groups: @@ -181,16 +190,16 @@ (((isotuple[1] == 1) and 1) or 0), days=-isotuple[2] + days) elif 'day' in groups: # ordinal date - return ret + timedelta(days=int(groups['day'])-1) + return ret + timedelta(days=int(groups['day']) - 1) else: # year date - return ret + return ret.replace(month=defaultmonth, day=defaultday) # year-, month-, or complete date if 'day' not in groups or groups['day'] is None: - day = 1 + day = defaultday else: day = int(groups['day']) return date(sign * int(groups['year']), - int(groups['month']) or 1, day) + int(groups['month']) or defaultmonth, day) raise ISO8601Error('Unrecognised ISO 8601 date format: %r' % datestring) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/isoduration.py new/isodate-0.6.0/src/isodate/isoduration.py --- old/isodate-0.5.4/src/isodate/isoduration.py 2015-04-01 06:44:00.000000000 +0200 +++ new/isodate-0.6.0/src/isodate/isoduration.py 2017-07-05 13:02:04.000000000 +0200 @@ -34,6 +34,8 @@ from decimal import Decimal import re +from six import string_types + from isodate.duration import Duration from isodate.isoerror import ISO8601Error from isodate.isodatetime import parse_datetime @@ -80,7 +82,7 @@ The alternative format does not support durations with years, months or days set to 0. """ - if not isinstance(datestring, basestring): + if not isinstance(datestring, string_types): raise TypeError("Expecting a string %r" % datestring) match = ISO8601_PERIOD_REGEX.match(datestring) if not match: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/isostrf.py new/isodate-0.6.0/src/isodate/isostrf.py --- old/isodate-0.5.4/src/isodate/isostrf.py 2014-02-27 01:24:12.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/isostrf.py 2017-07-06 03:59:29.000000000 +0200 @@ -48,7 +48,8 @@ DATE_EXT_ORD_COMPLETE = '%Y-%j' DATE_BAS_WEEK = '%YW%W' DATE_EXT_WEEK = '%Y-W%W' -DATE_MONTH = '%Y-%m' +DATE_BAS_MONTH = '%Y%m' +DATE_EXT_MONTH = '%Y-%m' DATE_YEAR = '%Y' DATE_CENTURY = '%C' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/isotime.py new/isodate-0.6.0/src/isodate/isotime.py --- old/isodate-0.5.4/src/isodate/isotime.py 2015-04-01 06:44:00.000000000 +0200 +++ new/isodate-0.6.0/src/isodate/isotime.py 2017-07-05 13:16:45.000000000 +0200 @@ -125,7 +125,7 @@ if 'second' in groups: # round to microseconds if fractional seconds are more precise second = Decimal(groups['second']).quantize(Decimal('.000001')) - microsecond = (second - int(second)) * long(1e6) + microsecond = (second - int(second)) * int(1e6) # int(...) ... no rounding # to_integral() ... rounding return time(int(groups['hour']), int(groups['minute']), @@ -134,7 +134,7 @@ if 'minute' in groups: minute = Decimal(groups['minute']) second = (minute - int(minute)) * 60 - microsecond = (second - int(second)) * long(1e6) + microsecond = (second - int(second)) * int(1e6) return time(int(groups['hour']), int(minute), int(second), int(microsecond.to_integral()), tzinfo) else: @@ -142,7 +142,7 @@ hour = Decimal(groups['hour']) minute = (hour - int(hour)) * 60 second = (minute - int(minute)) * 60 - microsecond = (second - int(second)) * long(1e6) + microsecond = (second - int(second)) * int(1e6) return time(int(hour), int(minute), int(second), int(microsecond.to_integral()), tzinfo) raise ISO8601Error('Unrecognised ISO 8601 time format: %r' % timestring) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/isotzinfo.py new/isodate-0.6.0/src/isodate/isotzinfo.py --- old/isodate-0.5.4/src/isodate/isotzinfo.py 2014-02-27 01:24:59.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/isotzinfo.py 2017-10-13 06:24:48.000000000 +0200 @@ -35,7 +35,7 @@ from isodate.tzinfo import UTC, FixedOffset, ZERO TZ_REGEX = r"(?P<tzname>(Z|(?P<tzsign>[+-])"\ - r"(?P<tzhour>[0-9]{2})(:(?P<tzmin>[0-9]{2}))?)?)" + r"(?P<tzhour>[0-9]{2})(:?(?P<tzmin>[0-9]{2}))?)?)" TZ_RE = re.compile(TZ_REGEX) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/tests/__init__.py new/isodate-0.6.0/src/isodate/tests/__init__.py --- old/isodate-0.5.4/src/isodate/tests/__init__.py 2014-02-27 01:31:03.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/tests/__init__.py 2017-07-05 12:37:18.000000000 +0200 @@ -46,5 +46,6 @@ test_pickle.test_suite(), ]) + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/tests/test_date.py new/isodate-0.6.0/src/isodate/tests/test_date.py --- old/isodate-0.5.4/src/isodate/tests/test_date.py 2014-02-27 01:48:31.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/tests/test_date.py 2017-07-06 03:59:29.000000000 +0200 @@ -30,7 +30,8 @@ import unittest from datetime import date from isodate import parse_date, ISO8601Error, date_isoformat -from isodate import DATE_CENTURY, DATE_YEAR, DATE_MONTH +from isodate import DATE_CENTURY, DATE_YEAR +from isodate import DATE_BAS_MONTH, DATE_EXT_MONTH from isodate import DATE_EXT_COMPLETE, DATE_BAS_COMPLETE from isodate import DATE_BAS_ORD_COMPLETE, DATE_EXT_ORD_COMPLETE from isodate import DATE_BAS_WEEK, DATE_BAS_WEEK_COMPLETE @@ -42,7 +43,8 @@ # and 6 digit years. TEST_CASES = {4: [('19', date(1901, 1, 1), DATE_CENTURY), ('1985', date(1985, 1, 1), DATE_YEAR), - ('1985-04', date(1985, 4, 1), DATE_MONTH), + ('1985-04', date(1985, 4, 1), DATE_EXT_MONTH), + ('198504', date(1985, 4, 1), DATE_BAS_MONTH), ('1985-04-12', date(1985, 4, 12), DATE_EXT_COMPLETE), ('19850412', date(1985, 4, 12), DATE_BAS_COMPLETE), ('1985102', date(1985, 4, 12), DATE_BAS_ORD_COMPLETE), @@ -56,7 +58,7 @@ ('1-W1-1', None, DATE_BAS_WEEK_COMPLETE)], 6: [('+0019', date(1901, 1, 1), DATE_CENTURY), ('+001985', date(1985, 1, 1), DATE_YEAR), - ('+001985-04', date(1985, 4, 1), DATE_MONTH), + ('+001985-04', date(1985, 4, 1), DATE_EXT_MONTH), ('+001985-04-12', date(1985, 4, 12), DATE_EXT_COMPLETE), ('+0019850412', date(1985, 4, 12), DATE_BAS_COMPLETE), ('+001985102', date(1985, 4, 12), DATE_BAS_ORD_COMPLETE), @@ -125,5 +127,6 @@ def load_tests(loader, tests, pattern): return test_suite() + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/tests/test_datetime.py new/isodate-0.6.0/src/isodate/tests/test_datetime.py --- old/isodate-0.5.4/src/isodate/tests/test_datetime.py 2014-11-06 19:37:54.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/tests/test_datetime.py 2017-10-13 06:24:48.000000000 +0200 @@ -63,6 +63,16 @@ '+0400'),), DATE_EXT_WEEK_COMPLETE + 'T' + TIME_EXT_MINUTE + TZ_HOUR, '1985-W15-5T10:15+04'), + ('1985-W15-5T10:15-0430', + datetime(1985, 4, 12, 10, 15, tzinfo=FixedOffset(-4, -30, + '-0430'),), + DATE_EXT_WEEK_COMPLETE + 'T' + TIME_EXT_MINUTE + TZ_BAS, + '1985-W15-5T10:15-0430'), + ('1985-W15-5T10:15+04:45', + datetime(1985, 4, 12, 10, 15, tzinfo=FixedOffset(4, 45, + '+04:45'),), + DATE_EXT_WEEK_COMPLETE + 'T' + TIME_EXT_MINUTE + TZ_EXT, + '1985-W15-5T10:15+04:45'), ('20110410T101225.123000Z', datetime(2011, 4, 10, 10, 12, 25, 123000, tzinfo=UTC), DATE_BAS_COMPLETE + 'T' + TIME_BAS_COMPLETE + ".%f" + TZ_BAS, @@ -142,5 +152,6 @@ def load_tests(loader, tests, pattern): return test_suite() + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/tests/test_duration.py new/isodate-0.6.0/src/isodate/tests/test_duration.py --- old/isodate-0.5.4/src/isodate/tests/test_duration.py 2015-08-06 00:34:35.000000000 +0200 +++ new/isodate-0.6.0/src/isodate/tests/test_duration.py 2017-07-06 00:21:49.000000000 +0200 @@ -313,6 +313,10 @@ self.assertEqual('10 years, 10 months, 10 days, 0:00:10', str(dur)) self.assertEqual('isodate.duration.Duration(10, 10, 0,' ' years=10, months=10)', repr(dur)) + dur = Duration(months=0) + self.assertEqual('0:00:00', str(dur)) + dur = Duration(months=1) + self.assertEqual('1 month, 0:00:00', str(dur)) def test_hash(self): ''' @@ -597,5 +601,6 @@ def load_tests(loader, tests, pattern): return test_suite() + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/tests/test_pickle.py new/isodate-0.6.0/src/isodate/tests/test_pickle.py --- old/isodate-0.5.4/src/isodate/tests/test_pickle.py 2014-11-06 19:22:38.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/tests/test_pickle.py 2017-07-05 13:06:52.000000000 +0200 @@ -1,5 +1,7 @@ import unittest -import cPickle as pickle + +from six.moves import cPickle as pickle + import isodate @@ -31,11 +33,17 @@ pikl = pickle.dumps(dur, proto) if dur != pickle.loads(pikl): raise Exception("not equal") - except Exception, e: + except Exception as e: failed.append("pickle proto %d failed (%s)" % (proto, repr(e))) self.assertEqual(len(failed), 0, "pickle protos failed: %s" % str(failed)) + def test_pickle_utc(self): + ''' + isodate.UTC objects remain the same after pickling. + ''' + self.assertTrue(isodate.UTC is pickle.loads(pickle.dumps(isodate.UTC))) + def test_suite(): ''' @@ -50,5 +58,6 @@ def load_tests(loader, tests, pattern): return test_suite() + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/tests/test_strf.py new/isodate-0.6.0/src/isodate/tests/test_strf.py --- old/isodate-0.5.4/src/isodate/tests/test_strf.py 2014-02-27 01:51:01.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/tests/test_strf.py 2017-07-05 12:38:21.000000000 +0200 @@ -131,5 +131,6 @@ def load_tests(loader, tests, pattern): return test_suite() + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/tests/test_time.py new/isodate-0.6.0/src/isodate/tests/test_time.py --- old/isodate-0.5.4/src/isodate/tests/test_time.py 2014-02-27 01:45:26.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/tests/test_time.py 2017-10-13 06:24:48.000000000 +0200 @@ -83,6 +83,12 @@ ('15:27:46-05', time(15, 27, 46, tzinfo=FixedOffset(-5, -0, '-05:00')), TIME_EXT_COMPLETE + TZ_HOUR), + ('15:27:46-05:30', time(15, 27, 46, + tzinfo=FixedOffset(-5, -30, '-05:30')), + TIME_EXT_COMPLETE + TZ_EXT), + ('15:27:46-0545', time(15, 27, 46, + tzinfo=FixedOffset(-5, -45, '-0545')), + TIME_EXT_COMPLETE + TZ_BAS), ('1:17:30', None, TIME_EXT_COMPLETE)] @@ -139,5 +145,6 @@ def load_tests(loader, tests, pattern): return test_suite() + if __name__ == '__main__': unittest.main(defaultTest='test_suite') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate/tzinfo.py new/isodate-0.6.0/src/isodate/tzinfo.py --- old/isodate-0.5.4/src/isodate/tzinfo.py 2014-02-27 01:25:37.000000000 +0100 +++ new/isodate-0.6.0/src/isodate/tzinfo.py 2017-07-05 20:34:06.000000000 +0200 @@ -36,10 +36,24 @@ ''' return ZERO + def __reduce__(self): + ''' + When unpickling a Utc object, return the default instance below, UTC. + ''' + return _Utc, () + + UTC = Utc() # the default instance for UTC. +def _Utc(): + ''' + Helper function for unpickling a Utc object. + ''' + return UTC + + class FixedOffset(tzinfo): ''' A class building tzinfo objects for fixed-offset time zones. @@ -138,5 +152,6 @@ tt = time.localtime(stamp) return tt.tm_isdst > 0 -LOCAL = LocalTimezone() + # the default instance for local time zone. +LOCAL = LocalTimezone() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate.egg-info/PKG-INFO new/isodate-0.6.0/src/isodate.egg-info/PKG-INFO --- old/isodate-0.5.4/src/isodate.egg-info/PKG-INFO 2015-08-06 00:56:38.000000000 +0200 +++ new/isodate-0.6.0/src/isodate.egg-info/PKG-INFO 2017-10-13 11:25:07.000000000 +0200 @@ -1,8 +1,8 @@ Metadata-Version: 1.1 Name: isodate -Version: 0.5.4 +Version: 0.6.0 Summary: An ISO 8601 date/time/duration parser and formatter -Home-page: http://cheeseshop.python.org/pypi/isodate +Home-page: https://github.com/gweis/isodate/ Author: Gerhard Weis Author-email: gerhard.w...@proclos.com License: BSD @@ -16,14 +16,11 @@ .. image:: https://coveralls.io/repos/gweis/isodate/badge.svg?branch=master :target: https://coveralls.io/r/gweis/isodate?branch=master :alt: Coveralls - .. image:: https://pypip.in/version/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ + .. image:: https://img.shields.io/pypi/v/isodate.svg + :target: https://pypi.python.org/pypi/isodate/ :alt: Latest Version - .. image:: https://pypip.in/download/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ - :alt: Downloads - .. image:: https://pypip.in/license/isodate/badge.svg - :target: https://pypi.python.org/pypi/isodate/ + .. image:: https://img.shields.io/pypi/l/isodate.svg + :target: https://pypi.python.org/pypi/isodate/ :alt: License @@ -121,14 +118,22 @@ The doc strings and unit tests should provide rather detailed information about the methods and their limitations. - The source release provides a *setup.py* script and a *buildout.cfg*. Both can - be used to run the unit tests included. + The source release provides a *setup.py* script, + which can be used to run the unit tests included. Source code is available at `<http://github.com/gweis/isodate>`_. CHANGES ======= + 0.6.0 (2017-10-13) + ------------------ + + - support incomplete month date (Fabien Loffredo) + - rely on duck typing when doing duration maths + - support ':' as separator in fractional time zones (usrenmae) + + 0.5.4 (2015-08-06) ------------------ @@ -265,9 +270,10 @@ Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet Classifier: Topic :: Software Development :: Libraries :: Python Modules diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate.egg-info/SOURCES.txt new/isodate-0.6.0/src/isodate.egg-info/SOURCES.txt --- old/isodate-0.5.4/src/isodate.egg-info/SOURCES.txt 2015-08-06 00:56:38.000000000 +0200 +++ new/isodate-0.6.0/src/isodate.egg-info/SOURCES.txt 2017-10-13 11:25:07.000000000 +0200 @@ -2,6 +2,7 @@ MANIFEST.in README.rst TODO.txt +setup.cfg setup.py src/isodate/__init__.py src/isodate/duration.py @@ -16,6 +17,7 @@ src/isodate.egg-info/PKG-INFO src/isodate.egg-info/SOURCES.txt src/isodate.egg-info/dependency_links.txt +src/isodate.egg-info/requires.txt src/isodate.egg-info/top_level.txt src/isodate/tests/__init__.py src/isodate/tests/test_date.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/isodate-0.5.4/src/isodate.egg-info/requires.txt new/isodate-0.6.0/src/isodate.egg-info/requires.txt --- old/isodate-0.5.4/src/isodate.egg-info/requires.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/isodate-0.6.0/src/isodate.egg-info/requires.txt 2017-10-13 11:25:07.000000000 +0200 @@ -0,0 +1 @@ +six