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)
|
||||
----------------
|
||||
|
||||
|
||||
- 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
|
||||
__repr__ method.
|
||||
[t-8ch]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ from icalendar.parser import Parameters
|
|||
from icalendar.parser import q_join
|
||||
from icalendar.parser import q_split
|
||||
from icalendar.parser_tools import DEFAULT_ENCODING
|
||||
from icalendar.parser_tools import data_encode
|
||||
from icalendar.prop import TypesFactory
|
||||
from icalendar.prop import vText, vDDDLists
|
||||
|
||||
|
|
@ -59,13 +58,13 @@ class Component(CaselessDict):
|
|||
directy, but rather one of the subclasses.
|
||||
"""
|
||||
|
||||
name = '' # must be defined in each component
|
||||
required = () # These properties are required
|
||||
singletons = () # These properties must only appear once
|
||||
multiple = () # may occur more than once
|
||||
exclusive = () # These properties are mutually exclusive
|
||||
inclusive = () # if any occurs the other(s) MUST occur
|
||||
# ('duration', 'repeat')
|
||||
name = None # should be defined in each component
|
||||
required = () # These properties are required
|
||||
singletons = () # These properties must only appear once
|
||||
multiple = () # may occur more than once
|
||||
exclusive = () # These properties are mutually exclusive
|
||||
inclusive = () # if any occurs the other(s) MUST occur
|
||||
# ('duration', 'repeat')
|
||||
ignore_exceptions = False # if True, and we cannot parse this
|
||||
# component, we will silently ignore
|
||||
# it, rather than let the exception
|
||||
|
|
@ -262,7 +261,7 @@ class Component(CaselessDict):
|
|||
"""Recursively traverses component and subcomponents. Returns sequence
|
||||
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()
|
||||
return self._walk(name)
|
||||
|
||||
|
|
@ -368,9 +367,6 @@ class Component(CaselessDict):
|
|||
'{st!r}'.format(**locals()))
|
||||
return comps[0]
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.name, data_encode(self))
|
||||
|
||||
def content_line(self, name, value, sorted=True):
|
||||
"""Returns property as content line.
|
||||
"""
|
||||
|
|
@ -396,6 +392,16 @@ class Component(CaselessDict):
|
|||
content_lines = self.content_lines(sorted=sorted)
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from icalendar.compat import iteritems
|
||||
from icalendar.parser_tools import to_unicode
|
||||
from icalendar.parser_tools import data_encode
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
|
|
@ -41,6 +40,9 @@ class CaselessDict(OrderedDict):
|
|||
super(CaselessDict, self).__delitem__(key)
|
||||
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):
|
||||
key = to_unicode(key)
|
||||
return super(CaselessDict, self).__getitem__(key.upper())
|
||||
|
|
@ -89,7 +91,7 @@ class CaselessDict(OrderedDict):
|
|||
return type(self)(super(CaselessDict, self).copy())
|
||||
|
||||
def __repr__(self):
|
||||
return 'CaselessDict(%s)' % dict(self)
|
||||
return '%s(%s)' % (self.name, dict(self))
|
||||
|
||||
def __eq__(self, other):
|
||||
return self is other or dict(self.items()) == dict(other.items())
|
||||
|
|
|
|||
|
|
@ -191,9 +191,6 @@ class Parameters(CaselessDict):
|
|||
# def decoded(self, name):
|
||||
# "returns a decoded value, or list of same"
|
||||
|
||||
def __repr__(self):
|
||||
return 'Parameters(%s)' % data_encode(self)
|
||||
|
||||
def to_ical(self, sorted=True):
|
||||
result = []
|
||||
items = list(self.items())
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from icalendar import vCalAddress
|
|||
from icalendar.tests import unittest
|
||||
|
||||
import icalendar
|
||||
import re
|
||||
|
||||
|
||||
class TestPropertyParams(unittest.TestCase):
|
||||
|
|
@ -205,3 +206,11 @@ END:VCALENDAR"""
|
|||
self.assertEqual(event['attendee'][0].params.to_ical(),
|
||||
b'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE')
|
||||
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 pytz
|
||||
import re
|
||||
|
||||
|
||||
class TestCalComponent(unittest.TestCase):
|
||||
|
|
@ -306,6 +307,46 @@ class TestCalComponent(unittest.TestCase):
|
|||
preserved_str = component.to_ical(sorted=False).splitlines()
|
||||
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):
|
||||
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue