commit python-icalendar for openSUSE:Factory
Hello community, here is the log from the commit of package python-icalendar for openSUSE:Factory checked in at 2017-01-25 23:26:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-icalendar (Old) and /work/SRC/openSUSE:Factory/.python-icalendar.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-icalendar" Changes: -------- --- /work/SRC/openSUSE:Factory/python-icalendar/python-icalendar.changes 2016-04-22 16:23:44.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-icalendar.new/python-icalendar.changes 2017-01-25 23:26:21.411443813 +0100 @@ -1,0 +2,44 @@ +Wed Jan 18 13:59:19 UTC 2017 - dmueller@suse.com + +- correct source url + +------------------------------------------------------------------- +Sat Jan 14 18:34:28 UTC 2017 - hpj@urpla.net + +- update to version 3.11.2 (2017-01-12) + - Run tests with python 3.5 and 3.6. [geier] + - Allow tests failing with pypy3 on travis.ci. [geier] + +- update to version 3.11.1 (2016-12-19) + - Encode error message before adding it to the stack of collected error + messages. + +- update to version 3.11 (2016-11-18) + - Successfully test with pypy and pypy3. [gforcada] + - Minor documentation update. [tpltnt] + +- update to version 3.10 (2016-05-26) + - Updated components description to better comply with RFC 5545. Refs #183. + [stlaz] + - Added PERIOD value type to date types. Also fixes incompatibilities + described in #184. Refs #189. [stlaz] + - Fix testsuite for use with dateutil>=2.5. Refs #195. [untitaker] + - Reintroduce cal.Component.is_broken that was removed with 3.9.2. Refs #185. + [geier] + +- update to version 3.9.2 (2016-02-05) + - Defined test_suite in setup.py. Now tests can be run via python setup.py + test. [geier] + - Fixed cal.Component.from_ical() representing an unknown component as one of + the known. [stlaz] + - Fixed possible IndexError exception during parsing of an ical string. [stlaz] + - When doing a boolean test on icalendar.cal.Component, always return True. + Before it was returning False due to CaselessDict, if it didn’t contain any + items. [stlaz] + - Fixed date-time being recognized as date or time during parsing. Added + better error handling to parsing from ical strings. [stlaz] + - Added __version__ attribute to init.py. [TomTry] + - Documentation fixes. [TomTry] + - Pep 8, UTF 8 headers, dict/list calls to literals. [thet] + +------------------------------------------------------------------- Old: ---- icalendar-3.9.1.tar.gz New: ---- icalendar-3.11.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-icalendar.spec ++++++ --- /var/tmp/diff_new_pack.OpiTSk/_old 2017-01-25 23:26:21.887372063 +0100 +++ /var/tmp/diff_new_pack.OpiTSk/_new 2017-01-25 23:26:21.891371460 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-icalendar # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 7/2011 - now open-slx GmbH <Sascha.Manns@open-slx.de> # Copyright (c) 2009 - 7/2011 Sascha Manns <saigkill@opensuse.org> # @@ -20,14 +20,14 @@ %define modname icalendar Name: python-%{modname} -Version: 3.9.1 +Version: 3.11.2 Release: 0 Summary: Python parser/generator of iCalendar files package +# please see https://github.com/collective/icalendar/issues/2 for re-licensing discussion License: BSD-2-Clause Group: Development/Languages/Python -# please see https://github.com/collective/icalendar/issues/2 for re-licensing discussion Url: http://icalendar.readthedocs.org -Source0: https://pypi.python.org/packages/source/i/icalendar/%{modname}-%{version}.tar.gz +Source0: https://pypi.io/packages/source/i/icalendar/%{modname}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: fdupes BuildRequires: python-devel ++++++ icalendar-3.9.1.tar.gz -> icalendar-3.11.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/CHANGES.rst new/icalendar-3.11.2/CHANGES.rst --- old/icalendar-3.9.1/CHANGES.rst 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/CHANGES.rst 2017-01-12 17:33:28.000000000 +0100 @@ -1,7 +1,96 @@ - Changelog ========= +3.11.2 (2017-01-12) +------------------- + +Bug fixes: + +- Run tests with python 3.5 and 3.6. + [geier] + +- Allow tests failing with pypy3 on travis.ci. + [geier] + + +3.11.1 (2016-12-19) +------------------- + +Bug fixes: + +- Encode error message before adding it to the stack of collected error messages. + + +3.11 (2016-11-18) +----------------- + +Fixes: + +- Successfully test with pypy and pypy3. [gforcada] + +- Minor documentation update. [tpltnt] + + +3.10 (2016-05-26) +----------------- + +New: + +- Updated components description to better comply with RFC 5545. + Refs #183. + [stlaz] + +- Added PERIOD value type to date types. + Also fixes incompatibilities described in #184. + Refs #189. + [stlaz] + +Fixes: + +- Fix testsuite for use with ``dateutil>=2.5``. + Refs #195. + [untitaker] + +- Reintroduce cal.Component.is_broken that was removed with 3.9.2. + Refs #185. + [geier] + + +3.9.2 (2016-02-05) +------------------ + +New: + +- Defined ``test_suite`` in setup.py. + Now tests can be run via ``python setup.py test``. + [geier] + +Fixes: + +- Fixed cal.Component.from_ical() representing an unknown component as one of the known. + [stlaz] + +- Fixed possible IndexError exception during parsing of an ical string. + [stlaz] + +- When doing a boolean test on ``icalendar.cal.Component``, always return ``True``. + Before it was returning ``False`` due to CaselessDict, if it didn't contain any items. + [stlaz] + +- Fixed date-time being recognized as date or time during parsing. + Added better error handling to parsing from ical strings. + [stlaz] + +- Added __version__ attribute to init.py. + [TomTry] + +- Documentation fixes. + [TomTry] + +- Pep 8, UTF 8 headers, dict/list calls to literals. + [thet] + + 3.9.1 (2015-09-08) ------------------ @@ -237,7 +326,7 @@ - Use @staticmethod decorator instead of wrapper function. [warvariuc, thet] -- Extend quoting of parameter values to all of those characters: ",;: ’'". +- Extend quoting of parameter values to all of those characters: ",;: â'". This fixes an outlook incompatibility with some characters. Fixes: #79, Fixes: #81. [warvariuc] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/PKG-INFO new/icalendar-3.11.2/PKG-INFO --- old/icalendar-3.9.1/PKG-INFO 2015-09-08 16:08:12.000000000 +0200 +++ new/icalendar-3.11.2/PKG-INFO 2017-01-12 17:33:29.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: icalendar -Version: 3.9.1 +Version: 3.11.2 Summary: iCalendar parser/generator Home-page: https://github.com/collective/icalendar Author: Plone Foundation @@ -105,10 +105,99 @@ -------------------------------------------------- TOTAL 1152 81 93% - Changelog ========= + 3.11.2 (2017-01-12) + ------------------- + + Bug fixes: + + - Run tests with python 3.5 and 3.6. + [geier] + + - Allow tests failing with pypy3 on travis.ci. + [geier] + + + 3.11.1 (2016-12-19) + ------------------- + + Bug fixes: + + - Encode error message before adding it to the stack of collected error messages. + + + 3.11 (2016-11-18) + ----------------- + + Fixes: + + - Successfully test with pypy and pypy3. [gforcada] + + - Minor documentation update. [tpltnt] + + + 3.10 (2016-05-26) + ----------------- + + New: + + - Updated components description to better comply with RFC 5545. + Refs #183. + [stlaz] + + - Added PERIOD value type to date types. + Also fixes incompatibilities described in #184. + Refs #189. + [stlaz] + + Fixes: + + - Fix testsuite for use with ``dateutil>=2.5``. + Refs #195. + [untitaker] + + - Reintroduce cal.Component.is_broken that was removed with 3.9.2. + Refs #185. + [geier] + + + 3.9.2 (2016-02-05) + ------------------ + + New: + + - Defined ``test_suite`` in setup.py. + Now tests can be run via ``python setup.py test``. + [geier] + + Fixes: + + - Fixed cal.Component.from_ical() representing an unknown component as one of the known. + [stlaz] + + - Fixed possible IndexError exception during parsing of an ical string. + [stlaz] + + - When doing a boolean test on ``icalendar.cal.Component``, always return ``True``. + Before it was returning ``False`` due to CaselessDict, if it didn't contain any items. + [stlaz] + + - Fixed date-time being recognized as date or time during parsing. + Added better error handling to parsing from ical strings. + [stlaz] + + - Added __version__ attribute to init.py. + [TomTry] + + - Documentation fixes. + [TomTry] + + - Pep 8, UTF 8 headers, dict/list calls to literals. + [thet] + + 3.9.1 (2015-09-08) ------------------ @@ -344,7 +433,7 @@ - Use @staticmethod decorator instead of wrapper function. [warvariuc, thet] - - Extend quoting of parameter values to all of those characters: ",;: ’'". + - Extend quoting of parameter values to all of those characters: ",;: â'". This fixes an outlook incompatibility with some characters. Fixes: #79, Fixes: #81. [warvariuc] @@ -637,6 +726,8 @@ Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/docs/credits.rst new/icalendar-3.11.2/docs/credits.rst --- old/icalendar-3.9.1/docs/credits.rst 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/docs/credits.rst 2017-01-12 17:33:28.000000000 +0100 @@ -36,6 +36,7 @@ - Ronan Dunklau <ronan@dunklau.fr> - Russ <russ@rw.id.au> - Sidnei da Silva <sidnei@enfoldsystems.com> +- Stanislav Láznička <slaznick@redhat.com> - Stanislav Ochotnicky <sochotnicky@redhat.com> - Stefan Schwarzer <sschwarzer@sschwarzer.net> - Thomas Bruederli <thomas@roundcube.net> @@ -49,6 +50,8 @@ - spanktar <spanky@kapanka.com> - tgecho <tgecho@gmail.com> - tisto <tisto@plone.org> +- TomTry <tom.try@gmail.com> +- Andreas Ruppen <andreas.ruppen@gmail.com> Find out who contributed:: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/docs/install.rst new/icalendar-3.11.2/docs/install.rst --- old/icalendar-3.9.1/docs/install.rst 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/docs/install.rst 2017-01-12 17:33:28.000000000 +0100 @@ -5,7 +5,7 @@ python setup.py install -If installation is successful, you be able to import the iCalendar +If installation is successful, you will be able to import the iCalendar package, like this::
import icalendar diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/docs/usage.rst new/icalendar-3.11.2/docs/usage.rst --- old/icalendar-3.9.1/docs/usage.rst 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/docs/usage.rst 2017-01-12 17:33:28.000000000 +0100 @@ -58,7 +58,7 @@ END:VCALENDAR
Inside the components there are properties with values. The values -have special types. like integer, text, datetime etc. These values are +have special types. Like integer, text, datetime etc. these values are encoded in a special text format in an iCalendar file. There are methods for converting to and from these encodings in the package. @@ -170,8 +170,8 @@ Property values are utf-8 encoded strings. This is impractical if you want to use the data for further -computation. Eg. the datetime format looks like this: -'20050404T080000'. But the package makes it simple to Parse and +computation. The datetime format for example looks like this: +'20050404T080000'. But the package makes it simple to parse and generate iCalendar formatted strings. Basically you can make the add() method do the thinking, or you can do it @@ -256,7 +256,7 @@ ------- Here is an example generating a complete iCal calendar file with a -single event that can be loaded into the Mozilla calendar +single event that can be loaded into the Mozilla calendar. Init the calendar:: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/setup.cfg new/icalendar-3.11.2/setup.cfg --- old/icalendar-3.9.1/setup.cfg 2015-09-08 16:08:12.000000000 +0200 +++ new/icalendar-3.11.2/setup.cfg 2017-01-12 17:33:29.000000000 +0100 @@ -1,3 +1,12 @@ +[check-manifest] +ignore = + *.cfg + bootstrap.py + requirements_docs.txt + +[zest.releaser] +python-file-with-version = src/icalendar/__init__.py + [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/setup.py new/icalendar-3.11.2/setup.py --- old/icalendar-3.9.1/setup.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/setup.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,9 +1,17 @@ +# -*- coding: utf-8 -*- import codecs import setuptools import sys +import re +import ast + +_version_re = re.compile(r'__version__\s+=\s+(.*)') + +with open('src/icalendar/__init__.py', 'rb') as f: + version = str(ast.literal_eval(_version_re.search( + f.read().decode('utf-8')).group(1))) -version = '3.9.1' shortdesc = 'iCalendar parser/generator' longdesc = codecs.open('README.rst', encoding='utf-8').read() longdesc += codecs.open('CHANGES.rst', encoding='utf-8').read() @@ -33,6 +41,8 @@ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', "Programming Language :: Python", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", @@ -54,5 +64,6 @@ install_requires=install_requires, extras_require={ 'test': tests_require - } + }, + test_suite='icalendar.tests' ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/__init__.py new/icalendar-3.11.2/src/icalendar/__init__.py --- old/icalendar-3.9.1/src/icalendar/__init__.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/__init__.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,6 @@ +# -*- coding: utf-8 -*- +__version__ = '3.11.2' + from icalendar.cal import ( Calendar, Event, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/cal.py new/icalendar-3.11.2/src/icalendar/cal.py --- old/icalendar-3.9.1/src/icalendar/cal.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/cal.py 2017-01-12 17:33:28.000000000 +0100 @@ -20,6 +20,8 @@ import dateutil.rrule from pytz.tzinfo import DstTzInfo +from icalendar.compat import unicode_type + ###################################### # The component factory @@ -72,7 +74,7 @@ # component, we will silently ignore # it, rather than let the exception # propagate upwards - # not_compliant = [''] # List of non-compliant properties. + # not_compliant = [''] # List of non-compliant properties. def __init__(self, *args, **kwargs): """Set keys to upper for initial dict. @@ -80,8 +82,8 @@ super(Component, self).__init__(*args, **kwargs) # set parameters here for properties that use non-default values self.subcomponents = [] # Components can be nested. - self.is_broken = False # True if we ignored an exception while - # parsing a property + self.errors = [] # If we ignored exception(s) while + # parsing a property, contains error strings # def is_compliant(self, name): # """Returns True is the given property name is compliant with the @@ -93,6 +95,23 @@ # """ # return name in not_compliant + def __bool__(self): + """Returns True, CaselessDict would return False if it had no items. + """ + return True + + # python 2 compatibility + __nonzero__ = __bool__ + + def is_empty(self): + """Returns True if Component has no items or subcomponents, else False. + """ + return True if not (list(self.values()) + self.subcomponents) else False # noqa + + @property + def is_broken(self): + return bool(self.errors) + ############################# # handling of property values @@ -309,14 +328,14 @@ try: name, params, vals = line.parts() - except ValueError: + except ValueError as e: # if unable to parse a line within a component # that ignores exceptions, mark the component # as broken and skip the line. otherwise raise. component = stack[-1] if stack else None if not component or not component.ignore_exceptions: raise - component.is_broken = True + component.errors.append((None, unicode_type(e))) continue uname = name.upper() @@ -325,7 +344,11 @@ # try and create one of the components defined in the spec, # otherwise get a general Components for robustness. c_name = vals.upper() - c_class = component_factory.get(c_name, cls) + c_class = component_factory.get(c_name, Component) + # If component factory cannot resolve ``c_name``, the generic + # ``Component`` class is used which does not have the name set. + # That's opposed to the usage of ``cls``, which represents a + # more concrete subclass with a name set (e.g. VCALENDAR). component = c_class() if not getattr(component, 'name', ''): # undefined components component.name = c_name @@ -338,8 +361,7 @@ if not stack: # we are at the end comps.append(component) else: - if not component.is_broken: - stack[-1].add_component(component) + stack[-1].add_component(component) if vals == 'VTIMEZONE' and \ 'TZID' in component and \ component['TZID'] not in pytz.all_timezones and \ @@ -348,7 +370,10 @@ # we are adding properties to the current top of the stack else: factory = types_factory.for_property(name) - component = stack[-1] + component = stack[-1] if stack else None + if not component: + raise ValueError('Property "{prop}" does not have ' + 'a parent component.'.format(prop=name)) datetime_names = ('DTSTART', 'DTEND', 'RECURRENCE-ID', 'DUE', 'FREEBUSY', 'RDATE', 'EXDATE') try: @@ -356,10 +381,11 @@ vals = factory(factory.from_ical(vals, params['TZID'])) else: vals = factory(factory.from_ical(vals)) - except ValueError: + except ValueError as e: if not component.ignore_exceptions: raise - component.is_broken = True + component.errors.append((uname, unicode_type(e))) + component.add(name, None, encode=0) else: vals.params = params component.add(name, vals, encode=0) @@ -412,7 +438,7 @@ ####################################### -# components defined in RFC 2445 +# components defined in RFC 5545 class Event(Component): @@ -420,21 +446,21 @@ canonical_order = ( 'SUMMARY', 'DTSTART', 'DTEND', 'DURATION', 'DTSTAMP', - 'UID', 'RECURRENCE-ID', 'SEQUENCE', - 'RRULE' 'EXRULE', 'RDATE', 'EXDATE', + 'UID', 'RECURRENCE-ID', 'SEQUENCE', 'RRULE', 'RDATE', + 'EXDATE', ) - required = ('UID',) + required = ('UID', 'DTSTAMP',) singletons = ( 'CLASS', 'CREATED', 'DESCRIPTION', 'DTSTART', 'GEO', 'LAST-MODIFIED', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'DTSTAMP', 'SEQUENCE', 'STATUS', 'SUMMARY', 'TRANSP', 'URL', 'RECURRENCE-ID', 'DTEND', 'DURATION', - 'DTSTART', + 'UID', ) - exclusive = ('DTEND', 'DURATION', ) + exclusive = ('DTEND', 'DURATION',) multiple = ( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'EXDATE', - 'EXRULE', 'RSTATUS', 'RELATED', 'RESOURCES', 'RDATE', 'RRULE' + 'RSTATUS', 'RELATED', 'RESOURCES', 'RDATE', 'RRULE' ) ignore_exceptions = True @@ -443,7 +469,7 @@ name = 'VTODO' - required = ('UID',) + required = ('UID', 'DTSTAMP',) singletons = ( 'CLASS', 'COMPLETED', 'CREATED', 'DESCRIPTION', 'DTSTAMP', 'DTSTART', 'GEO', 'LAST-MODIFIED', 'LOCATION', 'ORGANIZER', 'PERCENT-COMPLETE', @@ -453,7 +479,7 @@ exclusive = ('DUE', 'DURATION',) multiple = ( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'EXDATE', - 'EXRULE', 'RSTATUS', 'RELATED', 'RESOURCES', 'RDATE', 'RRULE' + 'RSTATUS', 'RELATED', 'RESOURCES', 'RDATE', 'RRULE' ) @@ -461,15 +487,14 @@ name = 'VJOURNAL' - required = ('UID',) + required = ('UID', 'DTSTAMP',) singletons = ( - 'CLASS', 'CREATED', 'DESCRIPTION', 'DTSTART', 'DTSTAMP', - 'LAST-MODIFIED', 'ORGANIZER', 'RECURRENCE-ID', 'SEQUENCE', 'STATUS', - 'SUMMARY', 'UID', 'URL', + 'CLASS', 'CREATED', 'DTSTART', 'DTSTAMP', 'LAST-MODIFIED', 'ORGANIZER', + 'RECURRENCE-ID', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL', ) multiple = ( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'EXDATE', - 'EXRULE', 'RELATED', 'RDATE', 'RRULE', 'RSTATUS', + 'RELATED', 'RDATE', 'RRULE', 'RSTATUS', 'DESCRIPTION', ) @@ -477,9 +502,9 @@ name = 'VFREEBUSY' - required = ('UID',) + required = ('UID', 'DTSTAMP',) singletons = ( - 'CONTACT', 'DTSTART', 'DTEND', 'DURATION', 'DTSTAMP', 'ORGANIZER', + 'CONTACT', 'DTSTART', 'DTEND', 'DTSTAMP', 'ORGANIZER', 'UID', 'URL', ) multiple = ('ATTENDEE', 'COMMENT', 'FREEBUSY', 'RSTATUS',) @@ -487,8 +512,8 @@ class Timezone(Component): name = 'VTIMEZONE' - canonical_order = ('TZID', 'STANDARD', 'DAYLIGHT',) - required = ('TZID', 'STANDARD', 'DAYLIGHT',) + canonical_order = ('TZID',) + required = ('TZID',) # it also requires one of components DAYLIGHT and STANDARD singletons = ('TZID', 'LAST-MODIFIED', 'TZURL',) @staticmethod @@ -553,8 +578,8 @@ """convert this VTIMEZONE component to a pytz.timezone object """ zone = str(self['TZID']) - transitions = list() - dst = dict() + transitions = [] + dst = {} for component in self.walk(): if type(component) == Timezone: continue @@ -579,7 +604,7 @@ # (utcoffset, dstoffset, name) # dstoffset = 0, if current transition is to standard time # = this_utcoffset - prev_standard_utcoffset, otherwise - transition_info = list() + transition_info = [] for num, (transtime, osfrom, osto, name) in enumerate(transitions): dst_offset = False if not dst[name]: @@ -599,10 +624,11 @@ break transition_info.append((osto, dst_offset, name)) - cls = type(zone, (DstTzInfo,), dict( - zone=zone, - _utc_transition_times=transition_times, - _transition_info=transition_info)) + cls = type(zone, (DstTzInfo,), { + 'zone': zone, + '_utc_transition_times': transition_times, + '_transition_info': transition_info + }) return cls() @@ -610,24 +636,28 @@ class TimezoneStandard(Component): name = 'STANDARD' required = ('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM') - singletons = ('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM', 'RRULE') - multiple = ('COMMENT', 'RDATE', 'TZNAME') + singletons = ('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM',) + multiple = ('COMMENT', 'RDATE', 'TZNAME', 'RRULE', 'EXDATE') class TimezoneDaylight(Component): name = 'DAYLIGHT' - required = ('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM') - singletons = ('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM', 'RRULE') - multiple = ('COMMENT', 'RDATE', 'TZNAME') + required = TimezoneStandard.required + singletons = TimezoneStandard.singletons + multiple = TimezoneStandard.multiple class Alarm(Component): name = 'VALARM' - # not quite sure about these ... + # some properties MAY/MUST/MUST NOT appear depending on ACTION value required = ('ACTION', 'TRIGGER',) - singletons = ('ATTACH', 'ACTION', 'TRIGGER', 'DURATION', 'REPEAT',) - inclusive = (('DURATION', 'REPEAT',),) + singletons = ( + 'ATTACH', 'ACTION', 'DESCRIPTION', 'SUMMARY', 'TRIGGER', + 'DURATION', 'REPEAT', + ) + inclusive = (('DURATION', 'REPEAT',), ('SUMMARY', 'ATTENDEE',)) + multiple = ('ATTENDEE', 'ATTACH') class Calendar(Component): @@ -635,9 +665,8 @@ """ name = 'VCALENDAR' canonical_order = ('VERSION', 'PRODID', 'CALSCALE', 'METHOD',) - required = ('prodid', 'version', ) - singletons = ('prodid', 'version', ) - multiple = ('calscale', 'method', ) + required = ('PRODID', 'VERSION', ) + singletons = ('PRODID', 'VERSION', 'CALSCALE', 'METHOD') # These are read only singleton, so one instance is enough for the module types_factory = TypesFactory() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/caselessdict.py new/icalendar-3.11.2/src/icalendar/caselessdict.py --- old/icalendar-3.9.1/src/icalendar/caselessdict.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/caselessdict.py 2017-01-12 17:33:28.000000000 +0100 @@ -21,8 +21,8 @@ def canonsort_items(dict1, canonical_order=None): """Returns a list of items from dict1, sorted by canonical_order. """ - return [(k, dict1[k]) for \ - k in canonsort_keys(dict1.keys(), canonical_order)] + return [(k, dict1[k]) for k + in canonsort_keys(dict1.keys(), canonical_order)] class CaselessDict(OrderedDict): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/compat.py new/icalendar-3.11.2/src/icalendar/compat.py --- old/icalendar-3.9.1/src/icalendar/compat.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/compat.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import sys diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/parser.py new/icalendar-3.11.2/src/icalendar/parser.py --- old/icalendar-3.9.1/src/icalendar/parser.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/parser.py 2017-01-12 17:33:28.000000000 +0100 @@ -78,8 +78,9 @@ except (UnicodeEncodeError, UnicodeDecodeError): pass else: - return fold_sep.join(line[i:i+limit-1] for i in - range(0, len(line), limit-1)) + return fold_sep.join( + line[i:i + limit - 1] for i in range(0, len(line), limit - 1) + ) ret_chars = [] byte_count = 0 @@ -341,7 +342,7 @@ return (name, params, values) except ValueError as exc: raise ValueError( - u"Content line could not be parsed into parts: %r: %s" + u"Content line could not be parsed into parts: '%s': %s" % (self, exc) ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/parser_tools.py new/icalendar-3.11.2/src/icalendar/parser_tools.py --- old/icalendar-3.9.1/src/icalendar/parser_tools.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/parser_tools.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from icalendar import compat diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/prop.py new/icalendar-3.11.2/src/icalendar/prop.py --- old/icalendar-3.9.1/src/icalendar/prop.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/prop.py 2017-01-12 17:33:28.000000000 +0100 @@ -18,17 +18,17 @@ ########################################################################### -iCalendar properties has values. The values are strongly typed. This module -defines these types, calling val.to_ical() on them, Will render them as defined +iCalendar properties have values. The values are strongly typed. This module +defines these types, calling val.to_ical() on them will render them as defined in rfc2445. If you pass any of these classes a Python primitive, you will have an object that can render itself as iCalendar formatted date. -Property Value Data Types starts with a 'v'. they all have an to_ical() and +Property Value Data Types start with a 'v'. they all have an to_ical() and from_ical() method. The to_ical() method generates a text string in the iCalendar format. The from_ical() method can parse this format and return a -primitive Python datatype. So it should allways be true that: +primitive Python datatype. So it should always be true that: x == vDataType.from_ical(VDataType(x).to_ical()) @@ -273,14 +273,17 @@ So this is practical. """ def __init__(self, dt): - if not isinstance(dt, (datetime, date, timedelta, time)): - raise ValueError('You must use datetime, date, timedelta or time') + if not isinstance(dt, (datetime, date, timedelta, time, tuple)): + raise ValueError('You must use datetime, date, timedelta, ' + 'time or tuple (for periods)') if isinstance(dt, datetime): - self.params = Parameters(dict(value='DATE-TIME')) + self.params = Parameters({'value': 'DATE-TIME'}) elif isinstance(dt, date): - self.params = Parameters(dict(value='DATE')) + self.params = Parameters({'value': 'DATE'}) elif isinstance(dt, time): - self.params = Parameters(dict(value='TIME')) + self.params = Parameters({'value': 'TIME'}) + elif isinstance(dt, tuple): + self.params = Parameters({'value': 'PERIOD'}) if (isinstance(dt, datetime) or isinstance(dt, time))\ and getattr(dt, 'tzinfo', False): @@ -303,8 +306,10 @@ return vDuration(dt).to_ical() elif isinstance(dt, time): return vTime(dt).to_ical() + elif isinstance(dt, tuple) and len(dt) == 2: + return vPeriod(dt).to_ical() else: - raise ValueError('Unknown date type') + raise ValueError('Unknown date type: {}'.format(type(dt))) @classmethod def from_ical(cls, ical, timezone=None): @@ -313,13 +318,19 @@ u = ical.upper() if u.startswith(('P', '-P', '+P')): return vDuration.from_ical(ical) - try: + if '/' in u: + return vPeriod.from_ical(ical) + + if len(ical) in (15, 16): return vDatetime.from_ical(ical, timezone=timezone) - except ValueError: - try: - return vDate.from_ical(ical) - except ValueError: - return vTime.from_ical(ical) + elif len(ical) == 8: + return vDate.from_ical(ical) + elif len(ical) in (6, 7): + return vTime.from_ical(ical) + else: + raise ValueError( + "Expected datetime, date, or time, got: '%s'" % ical + ) class vDate(object): @@ -329,7 +340,7 @@ if not isinstance(dt, date): raise ValueError('Value MUST be a date instance') self.dt = dt - self.params = Parameters(dict(value='DATE')) + self.params = Parameters({'value': 'DATE'}) def to_ical(self): s = "%04d%02d%02d" % (self.dt.year, self.dt.month, self.dt.day) @@ -555,7 +566,7 @@ sign = match['signal'] weekday = match['weekday'] relative = match['relative'] - if not weekday in vWeekday.week_days or sign not in '+-': + if weekday not in vWeekday.week_days or sign not in '+-': raise ValueError('Expected weekday abbrevation, got: %s' % self) self.relative = relative and int(relative) or None self.params = Parameters() @@ -589,7 +600,7 @@ def __new__(cls, value, encoding=DEFAULT_ENCODING): value = to_unicode(value, encoding=encoding) self = super(vFrequency, cls).__new__(cls, value) - if not self in vFrequency.frequencies: + if self not in vFrequency.frequencies: raise ValueError('Expected frequency, got: %s' % self) self.params = Parameters() return self @@ -713,7 +724,7 @@ self.dt = args[0] else: self.dt = time(*args) - self.params = Parameters(dict(value='TIME')) + self.params = Parameters({'value': 'TIME'}) def to_ical(self): return self.dt.strftime("%H%M%S") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/__init__.py new/icalendar-3.11.2/src/icalendar/tests/__init__.py --- old/icalendar-3.9.1/src/icalendar/tests/__init__.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/__init__.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # unittest/unittest2 importer import unittest if not hasattr(unittest.TestCase, 'assertIsNotNone'): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/apple_xlocation_test.py new/icalendar-3.11.2/src/icalendar/tests/apple_xlocation_test.py --- old/icalendar-3.9.1/src/icalendar/tests/apple_xlocation_test.py 1970-01-01 01:00:00.000000000 +0100 +++ new/icalendar-3.11.2/src/icalendar/tests/apple_xlocation_test.py 2017-01-12 17:33:28.000000000 +0100 @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +from icalendar.tests import unittest + +import datetime +import icalendar +import os +import pytz + +class TestEncoding(unittest.TestCase): + + def test_apple_xlocation(self): + """ + Test if error messages are encode properly. + """ + try: + directory = os.path.dirname(__file__) + data = open(os.path.join(directory, 'x_location.ics'), 'rb').read() + cal = icalendar.Calendar.from_ical(data) + for event in cal.walk('vevent'): + self.assertEqual(len(event.errors), 1, 'Got too many errors') + error = event.errors[0][1] + self.assertTrue(error.startswith(u'Content line could not be parsed into parts')) + + except UnicodeEncodeError as e: + self.fail("There is something wrong with encoding in the collected error messages") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_fixed_issues.py new/icalendar-3.11.2/src/icalendar/tests/test_fixed_issues.py --- old/icalendar-3.9.1/src/icalendar/tests/test_fixed_issues.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_fixed_issues.py 2017-01-12 17:33:28.000000000 +0100 @@ -200,7 +200,11 @@ END:VEVENT""" event = icalendar.Calendar.from_ical(ical_str) self.assertTrue(isinstance(event, icalendar.Event)) - self.assertTrue(event.is_broken) + self.assertTrue(event.is_broken) # REMOVE FOR NEXT MAJOR RELEASE + self.assertEqual( + event.errors, + [(None, "Content line could not be parsed into parts: 'X': Invalid content line")] # noqa + ) def test_issue_104__no_ignore_exceptions(self): """ @@ -334,3 +338,97 @@ recur.to_ical(), b'FREQ=YEARLY;BYDAY=1SU;BYMONTH=11' ) + + def test_issue_168(self): + """Issue #168 - Parsing invalid icalendars fails without any warning + https://github.com/collective/icalendar/issues/168 + """ + + event_str = """ +BEGIN:VCALENDAR +BEGIN:VEVENT +DTEND:20150905T100000Z +DTSTART:20150905T090000Z +X-APPLE-RADIUS=49.91307046514149 +UID:123 +END:VEVENT +END:VCALENDAR""" + + calendar = icalendar.Calendar.from_ical(event_str) + self.assertEqual( + calendar.to_ical(), + b'BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20150905T090000Z\r\n' + b'DTEND:20150905T100000Z\r\nUID:123\r\n' + b'END:VEVENT\r\nEND:VCALENDAR\r\n' + ) + + def test_index_error_issue(self): + """Found an issue where from_ical() would raise IndexError for + properties without parent components. + https://github.com/collective/icalendar/pull/179 + """ + + with self.assertRaises(ValueError): + icalendar.Calendar.from_ical('VERSION:2.0') + + def test_issue_178(self): + """Issue #178 - A component with an unknown/invalid name is represented + as one of the known components, the information about the original + component name is lost. + https://github.com/collective/icalendar/issues/178 + https://github.com/collective/icalendar/pull/180 + """ + + # Parsing of a nonstandard component + ical_str = '\r\n'.join(['BEGIN:MYCOMP', 'END:MYCOMP']) + cal = icalendar.Calendar.from_ical(ical_str) + self.assertEqual(cal.to_ical(), + b'BEGIN:MYCOMP\r\nEND:MYCOMP\r\n') + + # Nonstandard component inside other components, also has properties + ical_str = '\r\n'.join(['BEGIN:VCALENDAR', + 'BEGIN:UNKNOWN', + 'UID:1234', + 'END:UNKNOWN', + 'END:VCALENDAR']) + + cal = icalendar.Calendar.from_ical(ical_str) + self.assertEqual(cal.errors, []) + self.assertEqual(cal.to_ical(), + b'BEGIN:VCALENDAR\r\nBEGIN:UNKNOWN\r\nUID:1234\r\n' + b'END:UNKNOWN\r\nEND:VCALENDAR\r\n') + + # Nonstandard component is able to contain other components + ical_str = '\r\n'.join(['BEGIN:MYCOMPTOO', + 'DTSTAMP:20150121T080000', + 'BEGIN:VEVENT', + 'UID:12345', + 'DTSTART:20150122', + 'END:VEVENT', + 'END:MYCOMPTOO']) + cal = icalendar.Calendar.from_ical(ical_str) + self.assertEqual(cal.errors, []) + self.assertEqual(cal.to_ical(), + b'BEGIN:MYCOMPTOO\r\nDTSTAMP:20150121T080000\r\n' + b'BEGIN:VEVENT\r\nDTSTART:20150122\r\nUID:12345\r\n' + b'END:VEVENT\r\nEND:MYCOMPTOO\r\n') + + def test_issue_184(self): + """Issue #184 - Previous changes in code broke already broken + representation of PERIOD values - in a new way""" + + ical_str = ['BEGIN:VEVENT', + 'DTSTAMP:20150219T133000', + 'DTSTART:20150219T133000', + 'UID:1234567', + 'RDATE;VALUE=PERIOD:20150219T133000/PT10H', + 'END:VEVENT'] + + event = icalendar.Event.from_ical('\r\n'.join(ical_str)) + self.assertEqual(event.errors, []) + self.assertEqual(event.to_ical(), + b'BEGIN:VEVENT\r\nDTSTART:20150219T133000\r\n' + b'DTSTAMP:20150219T133000\r\nUID:1234567\r\n' + b'RDATE;VALUE=PERIOD:20150219T133000/PT10H\r\n' + b'END:VEVENT\r\n' + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_icalendar.py new/icalendar-3.11.2/src/icalendar/tests/test_icalendar.py --- old/icalendar-3.9.1/src/icalendar/tests/test_icalendar.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_icalendar.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,4 +1,4 @@ -# coding: utf-8 +# -*- coding: utf-8 -*- from icalendar.tests import unittest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_multiple.py new/icalendar-3.11.2/src/icalendar/tests/test_multiple.py --- old/icalendar-3.9.1/src/icalendar/tests/test_multiple.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_multiple.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from icalendar import Calendar from icalendar.prop import vText from icalendar.tests import unittest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_property_params.py new/icalendar-3.11.2/src/icalendar/tests/test_property_params.py --- old/icalendar-3.9.1/src/icalendar/tests/test_property_params.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_property_params.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,4 +1,4 @@ -# coding: utf-8 +# -*- coding: utf-8 -*- from icalendar import Calendar from icalendar import Event from icalendar import Parameters diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_time.py new/icalendar-3.11.2/src/icalendar/tests/test_time.py --- old/icalendar-3.9.1/src/icalendar/tests/test_time.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_time.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from icalendar.tests import unittest import datetime diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_timezoned.py new/icalendar-3.11.2/src/icalendar/tests/test_timezoned.py --- old/icalendar-3.9.1/src/icalendar/tests/test_timezoned.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_timezoned.py 2017-01-12 17:33:28.000000000 +0100 @@ -135,8 +135,8 @@ # references: #73,7430b66862346fe3a6a100ab25e35a8711446717 date = dateutil.parser.parse('2012-08-30T22:41:00Z') date2 = dateutil.parser.parse('2012-08-30T22:41:00 +02:00') - self.assertTrue(date.tzinfo.__module__ == 'dateutil.tz') - self.assertTrue(date2.tzinfo.__module__ == 'dateutil.tz') + self.assertTrue(date.tzinfo.__module__.startswith('dateutil.tz')) + self.assertTrue(date2.tzinfo.__module__.startswith('dateutil.tz')) # make sure, it's parsed properly and doesn't throw an error self.assertTrue(icalendar.vDDDTypes(date).to_ical() @@ -161,16 +161,20 @@ # for reasons (tm) the locally installed version of the time zone # database isn't always complete, therefore we only compare some # transition times - ny_transition_times = list() - ny_transition_info = list() + ny_transition_times = [] + ny_transition_info = [] for num, date in enumerate(pytz_new_york._utc_transition_times): - if datetime.datetime(1967, 4, 30, 7, 0) <= date <= datetime.datetime(2037, 11, 1, 6, 0): + if datetime.datetime(1967, 4, 30, 7, 0)\ + <= date <= datetime.datetime(2037, 11, 1, 6, 0): ny_transition_times.append(date) ny_transition_info.append(pytz_new_york._transition_info[num]) self.assertEqual(tz._utc_transition_times[:142], ny_transition_times) self.assertEqual(tz._transition_info[0:142], ny_transition_info) self.assertIn( - (datetime.timedelta(-1, 72000), datetime.timedelta(0, 3600), 'EDT'), + ( + datetime.timedelta(-1, 72000), + datetime.timedelta(0, 3600), 'EDT' + ), tz._tzinfos.keys() ) self.assertIn( @@ -259,21 +263,58 @@ ) self.assertEqual( tz._transition_info, - [(datetime.timedelta(0, 43200), datetime.timedelta(0), 'custom_Pacific/Fiji_19151026T000000')] + - 3 * [(datetime.timedelta(0, 46800), datetime.timedelta(0, 3600), 'custom_Pacific/Fiji_19981101T020000'), - (datetime.timedelta(0, 43200), datetime.timedelta(0), 'custom_Pacific/Fiji_19990228T030000'), ] + - 3 * [(datetime.timedelta(0, 46800), datetime.timedelta(0, 3600), 'custom_Pacific/Fiji_20101024T020000'), - (datetime.timedelta(0, 43200), datetime.timedelta(0), 'custom_Pacific/Fiji_19990228T030000'), ] + - 25 * [(datetime.timedelta(0, 46800), datetime.timedelta(0, 3600), 'custom_Pacific/Fiji_20101024T020000'), - (datetime.timedelta(0, 43200), datetime.timedelta(0), 'custom_Pacific/Fiji_20140119T020000'), ] + - [(datetime.timedelta(0, 46800), datetime.timedelta(0, 3600), 'custom_Pacific/Fiji_20101024T020000')] + [( + datetime.timedelta(0, 43200), + datetime.timedelta(0), + 'custom_Pacific/Fiji_19151026T000000' + )] + + 3 * [( + datetime.timedelta(0, 46800), + datetime.timedelta(0, 3600), + 'custom_Pacific/Fiji_19981101T020000' + ), ( + datetime.timedelta(0, 43200), + datetime.timedelta(0), + 'custom_Pacific/Fiji_19990228T030000') + ] + + 3 * [( + datetime.timedelta(0, 46800), + datetime.timedelta(0, 3600), + 'custom_Pacific/Fiji_20101024T020000' + ), ( + datetime.timedelta(0, 43200), + datetime.timedelta(0), + 'custom_Pacific/Fiji_19990228T030000' + )] + + 25 * [( + datetime.timedelta(0, 46800), + datetime.timedelta(0, 3600), + 'custom_Pacific/Fiji_20101024T020000' + ), ( + datetime.timedelta(0, 43200), + datetime.timedelta(0), + 'custom_Pacific/Fiji_20140119T020000' + )] + + [( + datetime.timedelta(0, 46800), + datetime.timedelta(0, 3600), + 'custom_Pacific/Fiji_20101024T020000' + )] ) self.assertIn( - (datetime.timedelta(0, 46800), datetime.timedelta(0, 3600), 'custom_Pacific/Fiji_19981101T020000'), + ( + datetime.timedelta(0, 46800), + datetime.timedelta(0, 3600), + 'custom_Pacific/Fiji_19981101T020000' + ), tz._tzinfos.keys() ) self.assertIn( - (datetime.timedelta(0, 43200), datetime.timedelta(0), 'custom_Pacific/Fiji_19990228T030000'), + ( + datetime.timedelta(0, 43200), + datetime.timedelta(0), + 'custom_Pacific/Fiji_19990228T030000' + ), tz._tzinfos.keys() ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_unit_cal.py new/icalendar-3.11.2/src/icalendar/tests/test_unit_cal.py --- old/icalendar-3.9.1/src/icalendar/tests/test_unit_cal.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_unit_cal.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from datetime import datetime from datetime import timedelta from icalendar.tests import unittest @@ -17,9 +18,14 @@ c = Component() c.name = 'VCALENDAR' + self.assertTrue(c) + self.assertTrue(c.is_empty()) + # Every key defines a property.A property can consist of either a # single item. This can be set with a single value... c['prodid'] = '-//max m//icalendar.mxm.dk/' + self.assertFalse(c.is_empty()) + self.assertEqual( c, Calendar({'PRODID': '-//max m//icalendar.mxm.dk/'}) @@ -33,7 +39,7 @@ 'PRODID': '-//max m//icalendar.mxm.dk/'}) ) - ### ADD MULTIPLE VALUES TO A PROPERTY + # ## ADD MULTIPLE VALUES TO A PROPERTY # if you use the add method you don't have to considder if a value is # a list or not. @@ -389,8 +395,9 @@ directory = tempfile.mkdtemp() open(os.path.join(directory, 'test.ics'), 'wb').write(cal.to_ical()) - # Parsing a complete calendar from a string will silently ignore bogus - # events. The bogosity in the following is the third EXDATE: it has an + # Parsing a complete calendar from a string will silently ignore wrong + # events but adding the error information to the component's 'errors' + # attribute. The error in the following is the third EXDATE: it has an # empty DATE. s = '\r\n'.join(('BEGIN:VCALENDAR', 'PRODID:-//Google Inc//Google Calendar 70.9054//EN', @@ -405,7 +412,7 @@ 'EXDATE;VALUE=DATE:20080311', 'END:VEVENT', 'BEGIN:VEVENT', - 'DESCRIPTION:Bogus event', + 'DESCRIPTION:Wrong event', 'DTSTART;VALUE=DATE:20080303', 'DTEND;VALUE=DATE:20080304', 'RRULE:FREQ=DAILY;UNTIL=20080323T235959Z', @@ -416,4 +423,9 @@ self.assertEqual( [e['DESCRIPTION'].to_ical() for e in icalendar.cal.Calendar.from_ical(s).walk('VEVENT')], - [b'Perfectly OK event']) + [b'Perfectly OK event', b'Wrong event']) + self.assertEqual( + [e.errors + for e in icalendar.cal.Calendar.from_ical(s).walk('VEVENT')], + [[], [('EXDATE', "Expected datetime, date, or time, got: ''")]] + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_unit_caselessdict.py new/icalendar-3.11.2/src/icalendar/tests/test_unit_caselessdict.py --- old/icalendar-3.9.1/src/icalendar/tests/test_unit_caselessdict.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_unit_caselessdict.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from icalendar.tests import unittest import icalendar @@ -40,8 +41,9 @@ def test_caselessdict_canonsort_items(self): canonsort_items = icalendar.caselessdict.canonsort_items - d = dict(i=7, c='at', a=3.5, l=(2, 3), e=[4, 5], n=13, d={'x': 'y'}, - r=1.0) + d = dict( + i=7, c='at', a=3.5, l=(2, 3), e=[4, 5], n=13, d={'x': 'y'}, r=1.0 + ) out = canonsort_items(d) self.assertEqual( @@ -59,7 +61,7 @@ def test_caselessdict_copy(self): CaselessDict = icalendar.caselessdict.CaselessDict - + original_dict = CaselessDict(key1='val1', key2='val2') copied_dict = original_dict.copy() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_unit_prop.py new/icalendar-3.11.2/src/icalendar/tests/test_unit_prop.py --- old/icalendar-3.9.1/src/icalendar/tests/test_unit_prop.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_unit_prop.py 2017-01-12 17:33:28.000000000 +0100 @@ -258,7 +258,7 @@ # Let's see how close we can get to one from the rfc: # FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30 - r = dict(freq='yearly', interval=2) + r = dict({'freq': 'yearly', 'interval': 2}) r.update({ 'bymonth': 1, 'byday': 'su', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/test_unit_tools.py new/icalendar-3.11.2/src/icalendar/tests/test_unit_tools.py --- old/icalendar-3.9.1/src/icalendar/tests/test_unit_tools.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tests/test_unit_tools.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from icalendar.tests import unittest from icalendar.tools import UIDGenerator diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tests/x_location.ics new/icalendar-3.11.2/src/icalendar/tests/x_location.ics --- old/icalendar-3.9.1/src/icalendar/tests/x_location.ics 1970-01-01 01:00:00.000000000 +0100 +++ new/icalendar-3.11.2/src/icalendar/tests/x_location.ics 2017-01-12 17:33:28.000000000 +0100 @@ -0,0 +1,48 @@ +BEGIN:VCALENDAR +PRODID:-//Google Inc//Google Calendar 70.9054//EN +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +X-WR-CALNAME:ITC +X-WR-TIMEZONE:Europe/Zurich +X-WR-CALDESC:ITC Bookings +BEGIN:VTIMEZONE +TZID:Europe/Zurich +X-LIC-LOCATION:Europe/Zurich +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +TZNAME:CEST +DTSTART:19700329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +TZNAME:CET +DTSTART:19701025T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +DTSTART;TZID=Europe/Zurich:20161028T140000 +DTEND;TZID=Europe/Zurich:20161028T143000 +RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR +DTSTAMP:20161031T192828Z +UID:BFE33ADD-5553-48B5-B5A5-F9DA5CA4C393 +CREATED:20161029T121229Z +DESCRIPTION:Some Description +LAST-MODIFIED:20161029T121229Z +LOCATION:Roadstar 16\n12764 Happyville\nDenmark +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Daily Sync +TRANSP:OPAQUE +X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-ADDRESS="Röadstar 16\n12764 Happyvi + lle\nDenmark";X-APPLE-MAPKIT-HANDLE=CAESARoSCWYTYFhHQBEGfw4hQCIBDQoHRGVubW + FyaxJES0hhcHB5dmlsbGUqSGFwcHl2aWxsZTIHSGFwcHl2aWxsZToEMTI3NjRCDQpSb2Fkc3Rh + cloCMTZiUm9hZHN0YXIgMTYBEU1vcmRvcgENCk1vcmRvcioSUm9hZHN0YXIgMTYyUm9hZHN0YX + IgMTYxMjc2NCBIYXBweXZpbGxlMgdEZW5tYXJrOThA=;X-APPLE-RADIUS=49.913058665846 + 98;X-APPLE-REFERENCEFRAME=1;X-TITLE=:geo:52.382762,7.528319 +END:VEVENT +END:VCALENDAR diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/timezone_cache.py new/icalendar-3.11.2/src/icalendar/timezone_cache.py --- old/icalendar-3.9.1/src/icalendar/timezone_cache.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/timezone_cache.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- # we save all timezone with TZIDs unknow to the TZDB in here -_timezone_cache = dict() +_timezone_cache = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar/tools.py new/icalendar-3.11.2/src/icalendar/tools.py --- old/icalendar-3.9.1/src/icalendar/tools.py 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar/tools.py 2017-01-12 17:33:28.000000000 +0100 @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from datetime import datetime from icalendar.parser_tools import to_unicode from icalendar.prop import vDatetime diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar.egg-info/PKG-INFO new/icalendar-3.11.2/src/icalendar.egg-info/PKG-INFO --- old/icalendar-3.9.1/src/icalendar.egg-info/PKG-INFO 2015-09-08 16:08:02.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar.egg-info/PKG-INFO 2017-01-12 17:33:29.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: icalendar -Version: 3.9.1 +Version: 3.11.2 Summary: iCalendar parser/generator Home-page: https://github.com/collective/icalendar Author: Plone Foundation @@ -105,10 +105,99 @@ -------------------------------------------------- TOTAL 1152 81 93% - Changelog ========= + 3.11.2 (2017-01-12) + ------------------- + + Bug fixes: + + - Run tests with python 3.5 and 3.6. + [geier] + + - Allow tests failing with pypy3 on travis.ci. + [geier] + + + 3.11.1 (2016-12-19) + ------------------- + + Bug fixes: + + - Encode error message before adding it to the stack of collected error messages. + + + 3.11 (2016-11-18) + ----------------- + + Fixes: + + - Successfully test with pypy and pypy3. [gforcada] + + - Minor documentation update. [tpltnt] + + + 3.10 (2016-05-26) + ----------------- + + New: + + - Updated components description to better comply with RFC 5545. + Refs #183. + [stlaz] + + - Added PERIOD value type to date types. + Also fixes incompatibilities described in #184. + Refs #189. + [stlaz] + + Fixes: + + - Fix testsuite for use with ``dateutil>=2.5``. + Refs #195. + [untitaker] + + - Reintroduce cal.Component.is_broken that was removed with 3.9.2. + Refs #185. + [geier] + + + 3.9.2 (2016-02-05) + ------------------ + + New: + + - Defined ``test_suite`` in setup.py. + Now tests can be run via ``python setup.py test``. + [geier] + + Fixes: + + - Fixed cal.Component.from_ical() representing an unknown component as one of the known. + [stlaz] + + - Fixed possible IndexError exception during parsing of an ical string. + [stlaz] + + - When doing a boolean test on ``icalendar.cal.Component``, always return ``True``. + Before it was returning ``False`` due to CaselessDict, if it didn't contain any items. + [stlaz] + + - Fixed date-time being recognized as date or time during parsing. + Added better error handling to parsing from ical strings. + [stlaz] + + - Added __version__ attribute to init.py. + [TomTry] + + - Documentation fixes. + [TomTry] + + - Pep 8, UTF 8 headers, dict/list calls to literals. + [thet] + + 3.9.1 (2015-09-08) ------------------ @@ -344,7 +433,7 @@ - Use @staticmethod decorator instead of wrapper function. [warvariuc, thet] - - Extend quoting of parameter values to all of those characters: ",;: ’'". + - Extend quoting of parameter values to all of those characters: ",;: â'". This fixes an outlook incompatibility with some characters. Fixes: #79, Fixes: #81. [warvariuc] @@ -637,6 +726,8 @@ Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/src/icalendar.egg-info/SOURCES.txt new/icalendar-3.11.2/src/icalendar.egg-info/SOURCES.txt --- old/icalendar-3.9.1/src/icalendar.egg-info/SOURCES.txt 2015-09-08 16:08:02.000000000 +0200 +++ new/icalendar-3.11.2/src/icalendar.egg-info/SOURCES.txt 2017-01-12 17:33:29.000000000 +0100 @@ -4,6 +4,7 @@ MANIFEST.in README.rst TODO.rst +setup.cfg setup.py tox.ini docs/Makefile @@ -32,6 +33,7 @@ src/icalendar.egg-info/top_level.txt src/icalendar/tests/__init__.py src/icalendar/tests/america_new_york.ics +src/icalendar/tests/apple_xlocation_test.py src/icalendar/tests/encoding.ics src/icalendar/tests/issue_112_missing_tzinfo_on_exdate.ics src/icalendar/tests/issue_53_parsing_failure.ics @@ -52,4 +54,5 @@ src/icalendar/tests/test_unit_prop.py src/icalendar/tests/test_unit_tools.py src/icalendar/tests/time.ics -src/icalendar/tests/timezoned.ics \ No newline at end of file +src/icalendar/tests/timezoned.ics +src/icalendar/tests/x_location.ics \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/icalendar-3.9.1/tox.ini new/icalendar-3.11.2/tox.ini --- old/icalendar-3.9.1/tox.ini 2015-09-08 16:07:59.000000000 +0200 +++ new/icalendar-3.11.2/tox.ini 2017-01-12 17:33:28.000000000 +0100 @@ -1,6 +1,6 @@ # to run for a specific environment, use ``tox -e ENVNAME`` [tox] -envlist = py26,py27,py33,py34 +envlist = py26,py27,py33,py34,py35,py36 [testenv] deps =
participants (1)
-
root@hilbertn.suse.de