kopia lustrzana https://github.com/collective/icalendar
				
				
				
			Change class representation for CaselessDict objects to always include the class name or the class' name attribute, if available. Also show subcomponents for Component objects.
							rodzic
							
								
									ba0b2e58a1
								
							
						
					
					
						commit
						fb34cc3998
					
				|  | @ -4,7 +4,12 @@ Changelog | ||||||
| 
 | 
 | ||||||
| 3.8 (unreleased) | 3.8 (unreleased) | ||||||
| ---------------- | ---------------- | ||||||
|   | 
 | ||||||
|  | - Change class representation for CaselessDict objects to always include the | ||||||
|  |   class name or the class' name attribute, if available. Also show | ||||||
|  |   subcomponents for Component objects. | ||||||
|  |   [thet] | ||||||
|  |    | ||||||
| - Don't use data_encode for CaselessDict class representation but use dict's | - Don't use data_encode for CaselessDict class representation but use dict's | ||||||
|   __repr__ method. |   __repr__ method. | ||||||
|   [t-8ch] |   [t-8ch] | ||||||
|  |  | ||||||
|  | @ -12,7 +12,6 @@ from icalendar.parser import Parameters | ||||||
| from icalendar.parser import q_join | from icalendar.parser import q_join | ||||||
| from icalendar.parser import q_split | from icalendar.parser import q_split | ||||||
| from icalendar.parser_tools import DEFAULT_ENCODING | from icalendar.parser_tools import DEFAULT_ENCODING | ||||||
| from icalendar.parser_tools import data_encode |  | ||||||
| from icalendar.prop import TypesFactory | from icalendar.prop import TypesFactory | ||||||
| from icalendar.prop import vText, vDDDLists | from icalendar.prop import vText, vDDDLists | ||||||
| 
 | 
 | ||||||
|  | @ -59,13 +58,13 @@ class Component(CaselessDict): | ||||||
|     directy, but rather one of the subclasses. |     directy, but rather one of the subclasses. | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     name = ''        # must be defined in each component |     name = None         # should be defined in each component | ||||||
|     required = ()    # These properties are required |     required = ()       # These properties are required | ||||||
|     singletons = ()  # These properties must only appear once |     singletons = ()     # These properties must only appear once | ||||||
|     multiple = ()    # may occur more than once |     multiple = ()       # may occur more than once | ||||||
|     exclusive = ()   # These properties are mutually exclusive |     exclusive = ()      # These properties are mutually exclusive | ||||||
|     inclusive = ()   # if any occurs the other(s) MUST occur |     inclusive = ()      # if any occurs the other(s) MUST occur | ||||||
|                      # ('duration', 'repeat') |                         # ('duration', 'repeat') | ||||||
|     ignore_exceptions = False   # if True, and we cannot parse this |     ignore_exceptions = False   # if True, and we cannot parse this | ||||||
|                                 # component, we will silently ignore |                                 # component, we will silently ignore | ||||||
|                                 # it, rather than let the exception |                                 # it, rather than let the exception | ||||||
|  | @ -262,7 +261,7 @@ class Component(CaselessDict): | ||||||
|         """Recursively traverses component and subcomponents. Returns sequence |         """Recursively traverses component and subcomponents. Returns sequence | ||||||
|         of same. If name is passed, only components with name will be returned. |         of same. If name is passed, only components with name will be returned. | ||||||
|         """ |         """ | ||||||
|         if not name is None: |         if name is not None: | ||||||
|             name = name.upper() |             name = name.upper() | ||||||
|         return self._walk(name) |         return self._walk(name) | ||||||
| 
 | 
 | ||||||
|  | @ -368,9 +367,6 @@ class Component(CaselessDict): | ||||||
|                              '{st!r}'.format(**locals())) |                              '{st!r}'.format(**locals())) | ||||||
|         return comps[0] |         return comps[0] | ||||||
| 
 | 
 | ||||||
|     def __repr__(self): |  | ||||||
|         return '%s(%s)' % (self.name, data_encode(self)) |  | ||||||
| 
 |  | ||||||
|     def content_line(self, name, value, sorted=True): |     def content_line(self, name, value, sorted=True): | ||||||
|         """Returns property as content line. |         """Returns property as content line. | ||||||
|         """ |         """ | ||||||
|  | @ -396,6 +392,16 @@ class Component(CaselessDict): | ||||||
|         content_lines = self.content_lines(sorted=sorted) |         content_lines = self.content_lines(sorted=sorted) | ||||||
|         return content_lines.to_ical() |         return content_lines.to_ical() | ||||||
| 
 | 
 | ||||||
|  |     def __repr__(self): | ||||||
|  |         """String representation of class with all of it's subcomponents. | ||||||
|  |         """ | ||||||
|  |         subs = ', '.join([str(it) for it in self.subcomponents]) | ||||||
|  |         return '%s(%s%s)' % ( | ||||||
|  |             self.name, | ||||||
|  |             dict(self), | ||||||
|  |             ', %s' % subs if subs else '' | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| ####################################### | ####################################### | ||||||
| # components defined in RFC 2445 | # components defined in RFC 2445 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,6 @@ | ||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| from icalendar.compat import iteritems | from icalendar.compat import iteritems | ||||||
| from icalendar.parser_tools import to_unicode | from icalendar.parser_tools import to_unicode | ||||||
| from icalendar.parser_tools import data_encode |  | ||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|     from collections import OrderedDict |     from collections import OrderedDict | ||||||
|  | @ -41,6 +40,9 @@ class CaselessDict(OrderedDict): | ||||||
|                 super(CaselessDict, self).__delitem__(key) |                 super(CaselessDict, self).__delitem__(key) | ||||||
|                 self[key_upper] = value |                 self[key_upper] = value | ||||||
| 
 | 
 | ||||||
|  |         # If name not set, use class name instead | ||||||
|  |         self.name = getattr(self, 'name', None) or type(self).__name__ | ||||||
|  | 
 | ||||||
|     def __getitem__(self, key): |     def __getitem__(self, key): | ||||||
|         key = to_unicode(key) |         key = to_unicode(key) | ||||||
|         return super(CaselessDict, self).__getitem__(key.upper()) |         return super(CaselessDict, self).__getitem__(key.upper()) | ||||||
|  | @ -89,7 +91,7 @@ class CaselessDict(OrderedDict): | ||||||
|         return type(self)(super(CaselessDict, self).copy()) |         return type(self)(super(CaselessDict, self).copy()) | ||||||
| 
 | 
 | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return 'CaselessDict(%s)' % dict(self) |         return '%s(%s)' % (self.name, dict(self)) | ||||||
| 
 | 
 | ||||||
|     def __eq__(self, other): |     def __eq__(self, other): | ||||||
|         return self is other or dict(self.items()) == dict(other.items()) |         return self is other or dict(self.items()) == dict(other.items()) | ||||||
|  |  | ||||||
|  | @ -191,9 +191,6 @@ class Parameters(CaselessDict): | ||||||
| #   def decoded(self, name): | #   def decoded(self, name): | ||||||
| #       "returns a decoded value, or list of same" | #       "returns a decoded value, or list of same" | ||||||
| 
 | 
 | ||||||
|     def __repr__(self): |  | ||||||
|         return 'Parameters(%s)' % data_encode(self) |  | ||||||
| 
 |  | ||||||
|     def to_ical(self, sorted=True): |     def to_ical(self, sorted=True): | ||||||
|         result = [] |         result = [] | ||||||
|         items = list(self.items()) |         items = list(self.items()) | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ from icalendar import vCalAddress | ||||||
| from icalendar.tests import unittest | from icalendar.tests import unittest | ||||||
| 
 | 
 | ||||||
| import icalendar | import icalendar | ||||||
|  | import re | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestPropertyParams(unittest.TestCase): | class TestPropertyParams(unittest.TestCase): | ||||||
|  | @ -205,3 +206,11 @@ END:VCALENDAR""" | ||||||
|         self.assertEqual(event['attendee'][0].params.to_ical(), |         self.assertEqual(event['attendee'][0].params.to_ical(), | ||||||
|                          b'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE') |                          b'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE') | ||||||
|         self.assertEqual(event['attendee'][0].params['cn'], u'RembrandXS') |         self.assertEqual(event['attendee'][0].params['cn'], u'RembrandXS') | ||||||
|  | 
 | ||||||
|  |     def test_repr(self): | ||||||
|  |         """Test correct class representation. | ||||||
|  |         """ | ||||||
|  |         it = Parameters(parameter1='Value1') | ||||||
|  |         self.assertTrue( | ||||||
|  |             re.match("Parameters\({u?'PARAMETER1': 'Value1'}\)", str(it)) | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ from icalendar.tests import unittest | ||||||
| 
 | 
 | ||||||
| import icalendar | import icalendar | ||||||
| import pytz | import pytz | ||||||
|  | import re | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TestCalComponent(unittest.TestCase): | class TestCalComponent(unittest.TestCase): | ||||||
|  | @ -306,6 +307,46 @@ class TestCalComponent(unittest.TestCase): | ||||||
|         preserved_str = component.to_ical(sorted=False).splitlines() |         preserved_str = component.to_ical(sorted=False).splitlines() | ||||||
|         assert preserved_str == component_str |         assert preserved_str == component_str | ||||||
| 
 | 
 | ||||||
|  |     def test_repr(self): | ||||||
|  |         """Test correct class representation. | ||||||
|  |         """ | ||||||
|  |         from icalendar.cal import Component, Calendar, Event | ||||||
|  | 
 | ||||||
|  |         component = Component() | ||||||
|  |         component['key1'] = 'value1' | ||||||
|  | 
 | ||||||
|  |         self.assertTrue( | ||||||
|  |             re.match("Component\({u?'KEY1': 'value1'}\)", str(component)) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         calendar = Calendar() | ||||||
|  |         calendar['key1'] = 'value1' | ||||||
|  | 
 | ||||||
|  |         self.assertTrue( | ||||||
|  |             re.match("VCALENDAR\({u?'KEY1': 'value1'}\)", str(calendar)) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         event = Event() | ||||||
|  |         event['key1'] = 'value1' | ||||||
|  | 
 | ||||||
|  |         self.assertTrue( | ||||||
|  |             re.match("VEVENT\({u?'KEY1': 'value1'}\)", str(event)) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         # Representation of nested Components | ||||||
|  |         calendar.add_component(event) | ||||||
|  |         nested = Component(key1='VALUE1', key2='VALUE2') | ||||||
|  |         nested.add_component(component) | ||||||
|  |         nested.add_component(calendar) | ||||||
|  |         nested.add_component(event) | ||||||
|  | 
 | ||||||
|  |         self.assertTrue( | ||||||
|  |             re.match( | ||||||
|  |                 "Component\({u?'KEY2': 'VALUE2', u?'KEY1': 'VALUE1'}, Component\({u?'KEY1': 'value1'}\), VCALENDAR\({u?'KEY1': 'value1'}, VEVENT\({u?'KEY1': 'value1'}\)\), VEVENT\({u?'KEY1': 'value1'}\)\)",  # nopep8 | ||||||
|  |                 str(nested) | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class TestCal(unittest.TestCase): | class TestCal(unittest.TestCase): | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Johannes Raggam
						Johannes Raggam