Source code for fbrelation.syntax.attributelist
'''
Defines classes for parsing attribute lists, which are comma-separated
key/value pairs, with values in double quotes and preceded by the equals sign::
<name>="<value>", <name>="<value>", ..., <name>="<value>"
'''
import re
from fbrelation.exceptions import ParsingError
[docs]class AttributeListSyntax(object):
'''
Represents the abstract syntax of an attribute list, consisting of a
collection of named attributes with associated values. Implements container
semantics (via `in` and `[]`) to allow easy access to these key-value
mappings.
'''
[docs] def __init__(self, attributes):
'''
Initializes a new attribute list syntax object with the given
dictionary of attribute-name-to-attribute-value mappings.
'''
self.attributes = attributes
[docs] def __contains__(self, key):
'''
Allows the use of the `in` keyword to determine whether an attribute
with the given name is present in the list.
'''
return key in self.attributes
[docs] def __getitem__(self, key):
'''
Allows the use of square-bracket notation to retrieve the value
associated with a specified attribute.
'''
return self.attributes[key]
[docs] def __str__(self):
'''
Converts the syntax object back to text.
'''
return ', '.join(
['%s="%s"' % (key, self[key]) for key in sorted(self.attributes)])
@classmethod
[docs] def parse(cls, text):
'''
Parses the given input text to produce a new AttributeListSyntax object.
:returns: the newly created attribute list structure.
:raises: a :class:`.ParsingError` if the syntax is invalid.
'''
# Parse the attribute mappings and collect them into a dictionary
attributes = {}
for mapping in text.split(','):
# Match each attribute mapping against a regular expression,
# capturing the attribute's name and value
match = re.match(r'([^="]*)=\s*"([^"]*)"', mapping)
if not match:
raise ParsingError(
'"%s": Invalid syntax for a box attribute mapping.' % text)
name, value = match.groups()
# Ensure that attribute names aren't duplicated
if name in attributes:
raise ParsingError(
'"%s": Attribute name "%s" is used more than once.' %
(text, name))
# Add the attribute mapping to the dictionary
attributes[name.strip()] = value.strip()
# Construct a new AttributeListSyntax object from the dictionary of
# attribute -> value mappings
return cls(attributes)