def test_ordered_default_dict(self): mapping = OrderedDefaultDict(lambda: 2) mapping['a'] += 4 mapping['b'] += 3 mapping['c'] += 2 self.assertEqual([('a', 6), ('b', 5), ('c', 4)], list(mapping.items())) self.assertEqual(['a', 'b', 'c'], list(mapping)) self.assertEqual(['a', 'b', 'c'], list(mapping.keys())) self.assertEqual(['c', 'b', 'a'], list(reversed(mapping))) self.assertEqual([6, 5, 4], list(mapping.values())) self.assertEqual(6, mapping['a']) d_value = mapping['d'] self.assertEqual(2, d_value) del mapping['d'] self.assertNotIn('d', mapping) d_value = mapping['d'] self.assertEqual(2, d_value) self.assertEqual(4, len(mapping)) mapping.pop('d') self.assertEqual(3, len(mapping)) mapping.pop('b') self.assertEqual(2, len(mapping)) self.assertEqual(['a', 'c'], list(mapping)) self.assertEqual(['a', 'c'], list(mapping.keys()))
def __init__(self, normalize_overrides=None, encoding='utf-8', wrap_width=None): self._map = OrderedDefaultDict(list) self.raw = None self.encoding = encoding self._normalize_overrides = normalize_overrides self._wrap_width = wrap_width
def test_ordered_default_dict(self): mapping = OrderedDefaultDict(lambda: 2) mapping['a'] += 4 mapping['b'] += 3 mapping['c'] += 2 self.assertEqual( [('a', 6), ('b', 5), ('c', 4)], list(mapping.items()) )
def test_ordered_default_dict(self): mapping = OrderedDefaultDict(lambda: 2) mapping['a'] += 4 mapping['b'] += 3 mapping['c'] += 2 self.assertEqual( [('a', 6), ('b', 5), ('c', 4)], list(mapping.items()) ) self.assertEqual(['a', 'b', 'c'], list(mapping)) self.assertEqual(['a', 'b', 'c'], list(mapping.keys())) self.assertEqual(['c', 'b', 'a'], list(reversed(mapping))) self.assertEqual([6, 5, 4], list(mapping.values())) self.assertEqual(6, mapping['a']) d_value = mapping['d'] self.assertEqual(2, d_value) del mapping['d'] self.assertNotIn('d', mapping) d_value = mapping['d'] self.assertEqual(2, d_value) self.assertEqual(4, len(mapping)) mapping.pop('d') self.assertEqual(3, len(mapping)) mapping.pop('b') self.assertEqual(2, len(mapping)) self.assertEqual(['a', 'c'], list(mapping)) self.assertEqual(['a', 'c'], list(mapping.keys()))
def test_ordered_default_dict_deep_copy(self): d1 = OrderedDefaultDict() d1['a'] = object() d2 = copy.deepcopy(d1) self.assertNotEqual(d1['a'], d2['a']) d2['b'] = 5 self.assertEqual(1, len(d1)) self.assertEqual(2, len(d2))
def __init__(self, normalize_overrides=None): self._map = OrderedDefaultDict(list) self.raw = None self.encoding = 'utf-8' self._normalize_overrides = normalize_overrides
class NameValueRecord(collections.MutableMapping): '''An ordered mapping of name-value pairs. Duplicated names are accepted. .. seealso:: http://tools.ietf.org/search/draft-kunze-anvl-02 ''' def __init__(self, normalize_overrides=None): self._map = OrderedDefaultDict(list) self.raw = None self.encoding = 'utf-8' self._normalize_overrides = normalize_overrides def parse(self, string, encoding_fallback='latin1', strict=True): '''Parse the string or bytes. Args: encoding_fallback: If the data is bytes, it will attempt to decode it as UTF-8, otherwise it will use the fallback (default Latin-1) which should preserve the bytes. script: If True, errors will not be ignored Raises: :class:`ValueError` if the record is malformed. ''' if isinstance(string, bytes): try: string = string.decode(self.encoding, 'strict') except UnicodeError: if encoding_fallback: string = string.decode(encoding_fallback) self.encoding = encoding_fallback else: raise if not self.raw: self.raw = string else: self.raw += string line_ending = guess_line_ending(string) lines = unfold_lines(string).split(line_ending) for line in lines: if line: if ':' not in line: if strict: raise ValueError('Field missing colon.') else: continue name, value = line.split(':', 1) name = name.strip() value = value.strip() self.add(name, value) def __getitem__(self, name): normalized_name = normalize_name(name, self._normalize_overrides) if normalized_name in self._map: if self._map[normalized_name]: return self._map[normalized_name][0] raise KeyError(name) def __setitem__(self, name, value): normalized_name = normalize_name(name, self._normalize_overrides) self._map[normalized_name][:] = (value,) def __delitem__(self, name): del self._map[normalize_name(name, self._normalize_overrides)] def __iter__(self): return iter(self._map) def __len__(self): return len(self._map) def add(self, name, value): '''Append the name-value pair to the record.''' normalized_name = normalize_name(name, self._normalize_overrides) self._map[normalized_name].append(value) def get_list(self, name): '''Return all the values for given name.''' normalized_name = normalize_name(name, self._normalize_overrides) return self._map[normalized_name] def get_all(self): '''Return an iterator of name-value pairs.''' for name, values in self._map.items(): for value in values: yield (name, value) def __str__(self): pairs = [] for name, value in self.get_all(): if value: pairs.append('{0}: {1}'.format(name, value)) else: pairs.append('{0}:'.format(name)) pairs.append('') return '\r\n'.join(pairs) def __bytes__(self): return str(self).encode(self.encoding)
class NameValueRecord(collections.MutableMapping): '''An ordered mapping of name-value pairs. Duplicated names are accepted. .. seealso:: http://tools.ietf.org/search/draft-kunze-anvl-02 ''' def __init__(self, normalize_overrides=None): self._map = OrderedDefaultDict(list) self.raw = None self.encoding = 'utf-8' self._normalize_overrides = normalize_overrides def parse(self, string, encoding_fallback='latin1', strict=True): '''Parse the string or bytes. Args: encoding_fallback: If the data is bytes, it will attempt to decode it as UTF-8, otherwise it will use the fallback (default Latin-1) which should preserve the bytes. script: If True, errors will not be ignored Raises: :class:`ValueError` if the record is malformed. ''' if isinstance(string, bytes): try: string = string.decode(self.encoding, 'strict') except UnicodeError: if encoding_fallback: string = string.decode(encoding_fallback) self.encoding = encoding_fallback else: raise if not self.raw: self.raw = string else: self.raw += string line_ending = guess_line_ending(string) lines = unfold_lines(string).split(line_ending) for line in lines: if line: if ':' not in line: if strict: raise ValueError('Field missing colon.') else: continue name, value = line.split(':', 1) name = name.strip() value = value.strip() self.add(name, value) def __getitem__(self, name): normalized_name = normalize_name(name, self._normalize_overrides) if normalized_name in self._map: if self._map[normalized_name]: return self._map[normalized_name][0] raise KeyError(name) def __setitem__(self, name, value): normalized_name = normalize_name(name, self._normalize_overrides) self._map[normalized_name][:] = (value, ) def __delitem__(self, name): del self._map[normalize_name(name, self._normalize_overrides)] def __iter__(self): return iter(self._map) def __len__(self): return len(self._map) def add(self, name, value): '''Append the name-value pair to the record.''' normalized_name = normalize_name(name, self._normalize_overrides) self._map[normalized_name].append(value) def get_list(self, name): '''Return all the values for given name.''' normalized_name = normalize_name(name, self._normalize_overrides) return self._map[normalized_name] def get_all(self): '''Return an iterator of name-value pairs.''' for name, values in self._map.items(): for value in values: yield (name, value) def __str__(self): pairs = [] for name, value in self.get_all(): if value: pairs.append('{0}: {1}'.format(name, value)) else: pairs.append('{0}:'.format(name)) pairs.append('') return '\r\n'.join(pairs) def __bytes__(self): return str(self).encode(self.encoding)
class NameValueRecord(collections.MutableMapping): '''An ordered mapping of name-value pairs. Duplicated names are accepted. .. seealso:: http://tools.ietf.org/search/draft-kunze-anvl-02 ''' def __init__(self, normalize_overrides=None, encoding='utf-8', wrap_width=None): self._map = OrderedDefaultDict(list) self.raw = None self.encoding = encoding self._normalize_overrides = normalize_overrides self._wrap_width = wrap_width def parse(self, string, strict=True): '''Parse the string or bytes. Args: strict (bool): If True, errors will not be ignored Raises: :class:`ValueError` if the record is malformed. ''' if isinstance(string, bytes): errors = 'strict' if strict else 'replace' string = string.decode(self.encoding, errors=errors) if not self.raw: self.raw = string else: self.raw += string lines = unfold_lines(string).splitlines() for line in lines: if line: if ':' not in line: if strict: raise ValueError('Field missing colon.') else: continue name, value = line.split(':', 1) name = name.strip() value = value.strip() self.add(name, value) def __getitem__(self, name): normalized_name = normalize_name(name, self._normalize_overrides) if normalized_name in self._map: if self._map[normalized_name]: return self._map[normalized_name][0] raise KeyError(name) def __setitem__(self, name, value): normalized_name = normalize_name(name, self._normalize_overrides) self._map[normalized_name][:] = (value, ) def __delitem__(self, name): del self._map[normalize_name(name, self._normalize_overrides)] def __iter__(self): return iter(self._map) def __len__(self): return len(self._map) def add(self, name, value): '''Append the name-value pair to the record.''' normalized_name = normalize_name(name, self._normalize_overrides) self._map[normalized_name].append(value) def get_list(self, name): '''Return all the values for given name.''' normalized_name = normalize_name(name, self._normalize_overrides) return self._map[normalized_name] def get_all(self): '''Return an iterator of name-value pairs.''' for name, values in self._map.items(): for value in values: yield (name, value) def __str__(self): return self.to_str() def to_str(self): '''Convert to string.''' pairs = [] for name, value in self.get_all(): if value and self._wrap_width: pairs.append('{0}:{1}'.format( name, '\r\n'.join( textwrap.wrap(value, width=self._wrap_width, drop_whitespace=False, initial_indent=' ', subsequent_indent=' ')))) elif value: pairs.append('{0}: {1}'.format(name, value)) else: pairs.append('{0}:'.format(name)) pairs.append('') return '\r\n'.join(pairs) def __bytes__(self): return self.to_bytes() def to_bytes(self, errors='strict'): '''Convert to bytes.''' return str(self).encode(self.encoding, errors=errors)