used bytestrings where appropriate

needed to introduce a unicode version of FOLD called uFOLD
some internal cleanup seems to be needed, not everything uses unicode
just yet
pull/113/head
Christian Geier 2013-10-20 22:21:00 +02:00
rodzic c32987cf12
commit fa22b7763e
2 zmienionych plików z 35 dodań i 31 usunięć

Wyświetl plik

@ -93,9 +93,10 @@ def param_value(value):
# Could be improved
NAME = re.compile('[\w-]+')
UNSAFE_CHAR = re.compile(b'[\x00-\x08\x0a-\x1f\x7F",:;]')
QUNSAFE_CHAR = re.compile(b'[\x00-\x08\x0a-\x1f\x7F"]')
UNSAFE_CHAR = re.compile('[\x00-\x08\x0a-\x1f\x7F",:;]')
QUNSAFE_CHAR = re.compile('[\x00-\x08\x0a-\x1f\x7F"]')
FOLD = re.compile(b'(\r?\n)+[ \t]')
uFOLD = re.compile(u'(\r?\n)+[ \t]')
NEWLINE = re.compile(r'\r?\n')
@ -328,7 +329,7 @@ class Contentline(compat.unicode_type):
"""
ical = to_unicode(ical)
# a fold is carriage return followed by either a space or a tab
return cls(FOLD.sub('', ical), strict=strict)
return cls(uFOLD.sub('', ical), strict=strict)
def to_ical(self):
"""Long content lines are folded so they are less than 75 characters.
@ -351,12 +352,13 @@ class Contentlines(list):
def from_ical(cls, st):
"""Parses a string into content lines.
"""
st = to_unicode(st)
try:
# a fold is carriage return followed by either a space or a tab
unfolded = FOLD.sub(b'', st)
unfolded = uFOLD.sub('', st)
lines = cls(Contentline(line) for
line in unfolded.splitlines() if line)
lines.append(b'') # '\r\n' at the end of every content line
lines.append('') # '\r\n' at the end of every content line
return lines
except:
raise

Wyświetl plik

@ -18,8 +18,8 @@ class TestPropertyParams(unittest.TestCase):
ical.add('organizer', cal_address)
ical_str = Calendar.to_ical(ical)
exp_str = """BEGIN:VCALENDAR\r\nORGANIZER;CN="Doe, John":"""\
"""mailto:john.doe@example.org\r\nEND:VCALENDAR\r\n"""
exp_str = b"""BEGIN:VCALENDAR\r\nORGANIZER;CN="Doe, John":"""\
b"""mailto:john.doe@example.org\r\nEND:VCALENDAR\r\n"""
self.assertEqual(ical_str, exp_str)
@ -34,23 +34,25 @@ class TestPropertyParams(unittest.TestCase):
vevent = Event()
vevent['ORGANIZER'] = cal_address
self.assertEqual(
vevent.to_ical(),
'BEGIN:VEVENT\r\n'
'ORGANIZER;CN="Джон Доу":mailto:john.doe@example.org\r\n'
'END:VEVENT\r\n'
vevent.to_ical().decode('utf-8'),
u'BEGIN:VEVENT\r\n'
u'ORGANIZER;CN="Джон Доу":mailto:john.doe@example.org\r\n'
u'END:VEVENT\r\n'
)
self.assertEqual(vevent['ORGANIZER'].params['CN'], 'Джон Доу')
self.assertEqual(vevent['ORGANIZER'].params['CN'],
'Джон Доу')
def test_quoting(self):
# not double-quoted
self._test_quoting(u"Aramis", 'Aramis')
self._test_quoting(u"Aramis", u'Aramis')
# if a space is present - enclose in double quotes
self._test_quoting(u"Aramis Alameda", '"Aramis Alameda"')
self._test_quoting(u"Aramis Alameda", u'"Aramis Alameda"')
# a single quote in parameter value - double quote the value
self._test_quoting("Aramis d'Alameda", '"Aramis d\'Alameda"')
self._test_quoting(u"Aramis d'Alameda", u'"Aramis d\'Alameda"')
# double quote is replaced with single quote
self._test_quoting("Aramis d\"Alameda", '"Aramis d\'Alameda"')
self._test_quoting(u"Арамис д'Аламеда", '"Арамис д\'Аламеда"')
self._test_quoting(u"Aramis d\"Alameda", u'"Aramis d\'Alameda"')
self._test_quoting(u"Арамис д'Аламеда", u'"Арамис д\'Аламеда"')
def _test_quoting(self, cn_param, cn_quoted):
"""
@ -63,8 +65,8 @@ class TestPropertyParams(unittest.TestCase):
vevent.add('ATTENDEE', attendee)
self.assertEqual(
vevent.to_ical(),
'BEGIN:VEVENT\r\nATTENDEE;CN=%s:test@mail.com\r\nEND:VEVENT\r\n'
% cn_quoted
b'BEGIN:VEVENT\r\nATTENDEE;CN=' + cn_quoted.encode('utf-8') +
b':test@mail.com\r\nEND:VEVENT\r\n'
)
def test_escaping(self):
@ -91,18 +93,18 @@ class TestPropertyParams(unittest.TestCase):
r'that, that; %th%%at%\ that:'
)
self.assertEqual(
vevent['ORGANIZER'].to_ical(),
r'это, то; that\ %th%%at%:'
vevent['ORGANIZER'].to_ical().decode('utf-8'),
u'это, то; that\\ %th%%at%:'
)
def test_parameters_class(self):
# Simple parameter:value pair
p = Parameters(parameter1='Value1')
self.assertEqual(p.to_ical(), 'PARAMETER1=Value1')
self.assertEqual(p.to_ical(), b'PARAMETER1=Value1')
# keys are converted to upper
self.assertEqual(p.keys(), ['PARAMETER1'])
self.assertEqual(list(p.keys()), ['PARAMETER1'])
# Parameters are case insensitive
self.assertEqual(p['parameter1'], 'Value1')
@ -110,22 +112,22 @@ class TestPropertyParams(unittest.TestCase):
# Parameter with list of values must be seperated by comma
p = Parameters({'parameter1': ['Value1', 'Value2']})
self.assertEqual(p.to_ical(), 'PARAMETER1=Value1,Value2')
self.assertEqual(p.to_ical(), b'PARAMETER1=Value1,Value2')
# Multiple parameters must be seperated by a semicolon
p = Parameters({'RSVP': 'TRUE', 'ROLE': 'REQ-PARTICIPANT'})
self.assertEqual(p.to_ical(), 'ROLE=REQ-PARTICIPANT;RSVP=TRUE')
self.assertEqual(p.to_ical(), b'ROLE=REQ-PARTICIPANT;RSVP=TRUE')
# Parameter values containing ',;:' must be double quoted
p = Parameters({'ALTREP': 'http://www.wiz.org'})
self.assertEqual(p.to_ical(), 'ALTREP="http://www.wiz.org"')
self.assertEqual(p.to_ical(), b'ALTREP="http://www.wiz.org"')
# list items must be quoted seperately
p = Parameters({'MEMBER': ['MAILTO:projectA@host.com',
'MAILTO:projectB@host.com']})
self.assertEqual(
p.to_ical(),
'MEMBER="MAILTO:projectA@host.com","MAILTO:projectB@host.com"'
b'MEMBER="MAILTO:projectA@host.com","MAILTO:projectB@host.com"'
)
# Now the whole sheebang
@ -134,8 +136,8 @@ class TestPropertyParams(unittest.TestCase):
'ALTREP': ['http://www.wiz.org', 'value4']})
self.assertEqual(
p.to_ical(),
('ALTREP="http://www.wiz.org",value4;PARAMETER1=Value1;'
'PARAMETER2=Value2,Value3')
(b'ALTREP="http://www.wiz.org",value4;PARAMETER1=Value1;'
b'PARAMETER2=Value2,Value3')
)
# We can also parse parameter strings
@ -198,7 +200,7 @@ END:VCALENDAR"""
event = cal.walk("VEVENT")[0]
event['attendee'][0]
self.assertEqual(event['attendee'][0].to_ical(),
'MAILTO:rembrand@xs4all.nl')
b'MAILTO:rembrand@xs4all.nl')
self.assertEqual(event['attendee'][0].params.to_ical(),
'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE')
b'CN=RembrandXS;PARTSTAT=NEEDS-ACTION;RSVP=TRUE')
self.assertEqual(event['attendee'][0].params['cn'], u'RembrandXS')