def make_matrix(self,kmerlen): """ Returns a matrix (2-D numpy array corresponding to the method specs of Shogun or SK) and a dict of sequence IDs :author Camilla Montonen (2014) >>> matrix1=Matrix(True,"Shogun") >>> matrix1.make_matrix(['AACC','AAAA','TGTT'],['>seq1','>seq2','>seq3'],2) Matrix has been successfully computed. This matrix will not be stored. >>> matrix1.datamatrix array([[ 0.57735027, 1. , 0.57735027], [ 0.57735027, 0. , 0.57735027], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0.57735027], [ 0.57735027, 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ], [ 0. , 0. , 0. ]]) >>> matrix1.sq_ids OrderedDict([(0, '>seq1'), (1, '>seq2'), (2, '>seq3')]) """ kmer_list=generate_kmers(kmerlen) #generate the reverse mapping list rc_map=generate_rcmap_table(kmerlen,kmer_list) #initialise the sq_id dict sq_ids=OrderedDict() #initialise the outer wrapper for the matrix matrix=[] #initialise each sample row matrix_row=0 for sequence in self.training_sequences: x=[0]*(4**kmerlen) for j in range(len(sequence)-kmerlen+1): x[rc_map[kmer2kmerid(sequence[j:j+kmerlen],kmerlen)]]+=1 if self.normalization: #make x into a numpy.array for the duration of the normalization x=numpy.array(x, numpy.double) x=x/(numpy.sqrt(numpy.sum(x**2))) x=x.tolist() #save the row matrix.append(x) #save the sequence id corresponding to the sample row sq_ids.__setitem__(matrix_row,self.training_ids[matrix_row]) matrix_row+=1 matrix=numpy.array(matrix) print "Matrix has been successfully computed. This matrix will be stored in self.datamatrix." self.data=matrix self.sq_id_dict=sq_ids
def __getitem__(self, key, *args, **kwargs): # Get the key and remove it from the cache, or raise KeyError value = OrderedDict.__getitem__(self, key) del self[key] # Insert the (key, value) pair on the front of the cache OrderedDict.__setitem__(self, key, value) # Return the value from the cache return value
def __setitem__(self, key, value, *args, **kwargs): # Key was inserted before, remove it so we put it at front later if key in self: del self[key] # Too much items on the cache, remove the least recent used elif len(self) >= self._maxsize: self.popitem(False) # Insert the (key, value) pair on the front of the cache OrderedDict.__setitem__(self, key, value, *args, **kwargs)
def __setitem__(self, key, value, *args, **kwargs): """ This method sets a key and sibling attribute with given value. :param key: Key. ( Object ) :param value: Value. ( Object ) :param \*args: Arguments. ( \* ) :param \*\*kwargs: Key / Value pairs. ( Key / Value pairs ) """ OrderedDict.__setitem__(self, key, value, *args, **kwargs) OrderedDict.__setattr__(self, key, value)
def __setitem__(self, key, value, *args, **kwargs): """ Sets a key and sibling attribute with given value. :param key: Key. :type key: object :param value: Value. :type value: object :param \*args: Arguments. :type \*args: \* :param \*\*kwargs: Key / Value pairs. :type \*\*kwargs: dict """ OrderedDict.__setitem__(self, key, value, *args, **kwargs) OrderedDict.__setattr__(self, key, value)
def __setattr__(self, attribute, value): """ This method sets both key and sibling attribute with given value. :param attribute: Attribute. ( Object ) :param value: Value. ( Object ) """ if sys.version_info[:2] <= (2, 6): if not attribute in ("_OrderedDict__map", "_OrderedDict__end"): OrderedDict.__setitem__(self, attribute, value) else: if hasattr(self, "_OrderedDict__root") and hasattr( self, "_OrderedDict__map"): if self._OrderedDict__root: OrderedDict.__setitem__(self, attribute, value) OrderedDict.__setattr__(self, attribute, value)
def __setattr__(self, attribute, value): """ Sets both key and sibling attribute with given value. :param attribute: Attribute. :type attribute: object :param value: Value. :type value: object """ if sys.version_info[:2] <= (2, 6): if not attribute in ("_OrderedDict__map", "_OrderedDict__end"): OrderedDict.__setitem__(self, attribute, value) else: if hasattr(self, "_OrderedDict__root") and hasattr(self, "_OrderedDict__map"): if self._OrderedDict__root: OrderedDict.__setitem__(self, attribute, value) OrderedDict.__setattr__(self, attribute, value)
def __setitem__(self, key, value): if key in self: del self[key] OrderedDict.__setitem__(self, key, value)
class SectionsFileParser(foundations.io.File): """ Defines methods to parse sections file format files, an alternative configuration file parser is available directly with Python: :class:`ConfigParser.ConfigParser`. The parser given by this class has some major differences with Python :class:`ConfigParser.ConfigParser`: - | Sections and attributes are stored in their appearance order by default. ( Using Python :class:`collections.OrderedDict` ) - | A default section ( **_default** ) will store orphans attributes ( Attributes appearing before any declared section ). - File comments are stored inside the :obj:`SectionsFileParser.comments` class property. - | Sections, attributes and values are whitespaces stripped by default but can also be stored with their leading and trailing whitespaces. - | Values are quotations markers stripped by default but can also be stored with their leading and trailing quotations markers. - Attributes are namespaced by default allowing sections merge without keys collisions. """ def __init__(self, file=None, splitters=("=", ":"), namespaceSplitter="|", commentLimiters=(";", "#"), commentMarker="#", quotationMarkers=("\"", "'", "`"), rawSectionContentIdentifier="__raw__", defaultsSection="_defaults", preserveOrder=True): """ Initializes the class. Usage:: >>> content = ["[Section A]\\n", "; Comment.\\n", "Attribute 1 = \\"Value A\\"\\n", "\\n", \ "[Section B]\\n", "Attribute 2 = \\"Value B\\"\\n"] >>> sectionsFileParser = SectionsFileParser() >>> sectionsFileParser.content = content >>> sectionsFileParser.parse(stripComments=False) <foundations.parsers.SectionsFileParser object at 0x293892011> >>> sectionsFileParser.sections.keys() [u'Section A', u'Section B'] >>> sectionsFileParser.comments OrderedDict([(u'Section A|#0', {u'content': u'Comment.', u'id': 0})]) :param file: Current file path. :type file: unicode :param splitters: Splitter characters. :type splitters: tuple or list :param namespaceSplitter: Namespace splitters character. :type namespaceSplitter: unicode :param commentLimiters: Comment limiters characters. :type commentLimiters: tuple or list :param commentMarker: Character use to prefix extracted comments idientifiers. :type commentMarker: unicode :param quotationMarkers: Quotation markers characters. :type quotationMarkers: tuple or list :param rawSectionContentIdentifier: Raw section content identifier. :type rawSectionContentIdentifier: unicode :param defaultsSection: Default section name. :type defaultsSection: unicode :param preserveOrder: Data order is preserved. :type preserveOrder: bool """ LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__)) foundations.io.File.__init__(self, file) # --- Setting class attributes. --- self.__splitters = None self.splitters = splitters self.__namespaceSplitter = None self.namespaceSplitter = namespaceSplitter self.__commentLimiters = None self.commentLimiters = commentLimiters self.__commentMarker = None self.commentMarker = commentMarker self.__quotationMarkers = None self.quotationMarkers = quotationMarkers self.__rawSectionContentIdentifier = None self.rawSectionContentIdentifier = rawSectionContentIdentifier self.__defaultsSection = None self.defaultsSection = defaultsSection self.__preserveOrder = None self.preserveOrder = preserveOrder if not preserveOrder: self.__sections = {} self.__comments = {} else: self.__sections = OrderedDict() self.__comments = OrderedDict() self.__parsingErrors = [] #****************************************************************************************************************** #*** Attributes properties. #****************************************************************************************************************** @property def splitters(self): """ Property for **self.__splitters** attribute. :return: self.__splitters. :rtype: tuple or list """ return self.__splitters @splitters.setter @foundations.exceptions.handleExceptions(AssertionError) def splitters(self, value): """ Setter for **self.__splitters** attribute. :param value: Attribute value. :type value: tuple or list """ if value is not None: assert type(value) in (tuple, list), "'{0}' attribute: '{1}' type is not 'tuple' or 'list'!".format( "splitters", value) for element in value: assert type(element) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "splitters", element) assert len(element) == 1, "'{0}' attribute: '{1}' has multiples characters!".format("splitter", element) assert not re.search(r"\w", element), "'{0}' attribute: '{1}' is an alphanumeric character!".format( "splitter", element) self.__splitters = value @splitters.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def splitters(self): """ Deleter for **self.__splitters** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "splitters")) @property def namespaceSplitter(self): """ Property for **self.__namespaceSplitter** attribute. :return: self.__namespaceSplitter. :rtype: unicode """ return self.__namespaceSplitter @namespaceSplitter.setter @foundations.exceptions.handleExceptions(AssertionError) def namespaceSplitter(self, value): """ Setter for **self.__namespaceSplitter** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "namespaceSplitter", value) assert len(value) == 1, "'{0}' attribute: '{1}' has multiples characters!".format("namespaceSplitter", value) assert not re.search(r"\w", value), "'{0}' attribute: '{1}' is an alphanumeric character!".format( "namespaceSplitter", value) self.__namespaceSplitter = value @namespaceSplitter.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def namespaceSplitter(self): """ Deleter for **self.__namespaceSplitter** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "namespaceSplitter")) @property def commentLimiters(self): """ Property for **self.__commentLimiters** attribute. :return: self.__commentLimiters. :rtype: tuple or list """ return self.__commentLimiters @commentLimiters.setter @foundations.exceptions.handleExceptions(AssertionError) def commentLimiters(self, value): """ Setter for **self.__commentLimiters** attribute. :param value: Attribute value. :type value: tuple or list """ if value is not None: assert type(value) in (tuple, list), "'{0}' attribute: '{1}' type is not 'tuple' or 'list'!".format( "commentLimiters", value) for element in value: assert type(element) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "commentLimiters", element) self.__commentLimiters = value @commentLimiters.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def commentLimiters(self): """ Deleter for **self.__commentLimiters** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "commentLimiters")) @property def commentMarker(self): """ Property for **self.__commentMarker** attribute. :return: self.__commentMarker. :rtype: unicode """ return self.__commentMarker @commentMarker.setter @foundations.exceptions.handleExceptions(AssertionError) def commentMarker(self, value): """ Setter for **self.__commentMarker** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "commentMarker", value) assert not re.search(r"\w", value), "'{0}' attribute: '{1}' is an alphanumeric character!".format( "commentMarker", value) self.__commentMarker = value @commentMarker.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def commentMarker(self): """ Deleter for **self.__commentMarker** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "commentMarker")) @property def quotationMarkers(self): """ Property for **self.__quotationMarkers** attribute. :return: self.__quotationMarkers. :rtype: tuple or list """ return self.__quotationMarkers @quotationMarkers.setter @foundations.exceptions.handleExceptions(AssertionError) def quotationMarkers(self, value): """ Setter for **self.__quotationMarkers** attribute. :param value: Attribute value. :type value: tuple or list """ if value is not None: assert type(value) in (tuple, list), "'{0}' attribute: '{1}' type is not 'tuple' or 'list'!".format( "quotationMarkers", value) for element in value: assert type(element) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "quotationMarkers", element) assert len(element) == 1, "'{0}' attribute: '{1}' has multiples characters!".format("quotationMarkers", element) assert not re.search(r"\w", element), "'{0}' attribute: '{1}' is an alphanumeric character!".format( "quotationMarkers", element) self.__quotationMarkers = value @quotationMarkers.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def quotationMarkers(self): """ Deleter for **self.__quotationMarkers** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "quotationMarkers")) @property def rawSectionContentIdentifier(self): """ Property for **self. __rawSectionContentIdentifier** attribute. :return: self.__rawSectionContentIdentifier. :rtype: unicode """ return self.__rawSectionContentIdentifier @rawSectionContentIdentifier.setter @foundations.exceptions.handleExceptions(AssertionError) def rawSectionContentIdentifier(self, value): """ Setter for **self. __rawSectionContentIdentifier** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "rawSectionContentIdentifier", value) self.__rawSectionContentIdentifier = value @rawSectionContentIdentifier.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def rawSectionContentIdentifier(self): """ Deleter for **self. __rawSectionContentIdentifier** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "rawSectionContentIdentifier")) @property def defaultsSection(self): """ Property for **self.__defaultsSection** attribute. :return: self.__defaultsSection. :rtype: unicode """ return self.__defaultsSection @defaultsSection.setter @foundations.exceptions.handleExceptions(AssertionError) def defaultsSection(self, value): """ Setter for **self.__defaultsSection** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "defaultsSection", value) self.__defaultsSection = value @defaultsSection.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def defaultsSection(self): """ Deleter for **self.__defaultsSection** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultsSection")) @property def sections(self): """ Property for **self.__sections** attribute. :return: self.__sections. :rtype: OrderedDict or dict """ return self.__sections @sections.setter @foundations.exceptions.handleExceptions(AssertionError) def sections(self, value): """ Setter for **self.__sections** attribute. :param value: Attribute value. :type value: OrderedDict or dict """ if value is not None: assert type(value) in (OrderedDict, dict), "'{0}' attribute: '{1}' type is not \ 'OrderedDict' or 'dict'!".format("sections", value) for key, element in value.iteritems(): assert type(key) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "sections", key) assert type(element) in (OrderedDict, dict), "'{0}' attribute: '{1}' type is not \ 'OrderedDict' or 'dict'!".format("sections", key) self.__sections = value @sections.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def sections(self): """ Deleter for **self.__sections** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "sections")) @property def comments(self): """ Property for **self.__comments** attribute. :return: self.__comments. :rtype: OrderedDict or dict """ return self.__comments @comments.setter @foundations.exceptions.handleExceptions(AssertionError) def comments(self, value): """ Setter for **self.__comments** attribute. :param value: Attribute value. :type value: OrderedDict or dict """ if value is not None: assert type(value) in (OrderedDict, dict), "'{0}' attribute: '{1}' type is not \ 'OrderedDict' or 'dict'!".format("comments", value) for key, element in value.iteritems(): assert type(key) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "comments", key) assert type(element) in (OrderedDict, dict), "'{0}' attribute: '{1}' type is not \ 'OrderedDict' or 'dict'!".format("comments", key) self.__comments = value @comments.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def comments(self): """ Deleter for **self.__comments** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "comments")) @property def parsingErrors(self): """ Property for **self.__parsingErrors** attribute. :return: self.__parsingErrors. :rtype: list """ return self.__parsingErrors @parsingErrors.setter @foundations.exceptions.handleExceptions(AssertionError) def parsingErrors(self, value): """ Setter for **self.__parsingErrors** attribute. :param value: Attribute value. :type value: list """ if value is not None: assert type(value) is list, "'{0}' attribute: '{1}' type is not 'list'!".format("parsingErrors", value) for element in value: assert issubclass(element.__class__, foundations.exceptions.AbstractParsingError), \ "'{0}' attribute: '{1}' is not a '{2}' subclass!".format( "parsingErrors", element, foundations.exceptions.AbstractParsingError.__class__.__name__) self.__parsingErrors = value @parsingErrors.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def parsingErrors(self): """ Deleter for **self.__parsingErrors** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "parsingErrors")) @property def preserveOrder(self): """ Property for **self.__preserveOrder** attribute. :return: self.__preserveOrder. :rtype: bool """ return self.__preserveOrder @preserveOrder.setter @foundations.exceptions.handleExceptions(AssertionError) def preserveOrder(self, value): """ Setter method for **self.__preserveOrder** attribute. :param value: Attribute value. :type value: bool """ if value is not None: assert type(value) is bool, "'{0}' attribute: '{1}' type is not 'bool'!".format("preserveOrder", value) self.__preserveOrder = value @preserveOrder.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def preserveOrder(self): """ Deleter method for **self.__preserveOrder** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "preserveOrder")) #****************************************************************************************************************** #*** Class methods. #****************************************************************************************************************** def __getitem__(self, section): """ Reimplements the :meth:`object.__getitem__` method. :param section: Section name. :type section: unicode :return: Layout. :rtype: Layout """ return self.__sections.__getitem__(section) def __setitem__(self, section, value): """ Reimplements the :meth:`object.__getitem__` method. :param section: Section name. :type section: unicode :param section: Value. :type section: dict :return: Layout. :rtype: Layout """ return self.__sections.__setitem__(section, value) def __iter__(self): """ Reimplements the :meth:`object.__iter__` method. :return: Layouts iterator. :rtype: object """ return self.__sections.iteritems() def __contains__(self, section): """ Reimplements the :meth:`object.__contains__` method. :param section: Section name. :type section: unicode :return: Section existence. :rtype: bool """ return self.sectionExists(section) def __len__(self): """ Reimplements the :meth:`object.__len__` method. :return: Sections count. :rtype: int """ return len(self.__sections) @foundations.exceptions.handleExceptions(foundations.exceptions.FileStructureParsingError) def parse(self, rawSections=None, namespaces=True, stripComments=True, stripWhitespaces=True, stripQuotationMarkers=True, raiseParsingErrors=True): """ Process the file content and extracts the sections / attributes as nested :class:`collections.OrderedDict` dictionaries or dictionaries. Usage:: >>> content = ["; Comment.\\n", "Attribute 1 = \\"Value A\\"\\n", "Attribute 2 = \\"Value B\\"\\n"] >>> sectionsFileParser = SectionsFileParser() >>> sectionsFileParser.content = content >>> sectionsFileParser.parse(stripComments=False) <foundations.parsers.SectionsFileParser object at 0x860323123> >>> sectionsFileParser.sections.keys() [u'_defaults'] >>> sectionsFileParser.sections["_defaults"].values() [u'Value A', u'Value B'] >>> sectionsFileParser.parse(stripComments=False, stripQuotationMarkers=False) <foundations.parsers.SectionsFileParser object at 0x860323123> >>> sectionsFileParser.sections["_defaults"].values() [u'"Value A"', u'"Value B"'] >>> sectionsFileParser.comments OrderedDict([(u'_defaults|#0', {u'content': u'Comment.', u'id': 0})]) >>> sectionsFileParser.parse() <foundations.parsers.SectionsFileParser object at 0x860323123> >>> sectionsFileParser.sections["_defaults"] OrderedDict([(u'_defaults|Attribute 1', u'Value A'), (u'_defaults|Attribute 2', u'Value B')]) >>> sectionsFileParser.parse(namespaces=False) <foundations.parsers.SectionsFileParser object at 0x860323123> >>> sectionsFileParser.sections["_defaults"] OrderedDict([(u'Attribute 1', u'Value A'), (u'Attribute 2', u'Value B')]) :param rawSections: Ignored raw sections. :type rawSections: tuple or list :param namespaces: Attributes and comments are namespaced. :type namespaces: bool :param stripComments: Comments are stripped. :type stripComments: bool :param stripWhitespaces: Whitespaces are stripped. :type stripWhitespaces: bool :param stripQuotationMarkers: Attributes values quotation markers are stripped. :type stripQuotationMarkers: bool :param raiseParsingErrors: Raise parsing errors. :type raiseParsingErrors: bool :return: SectionFileParser instance. :rtype: SectionFileParser """ LOGGER.debug("> Reading sections from: '{0}'.".format(self.path)) if not self.content: self.read() attributes = {} if not self.__preserveOrder else OrderedDict() section = self.__defaultsSection rawSections = rawSections or [] commentId = 0 for i, line in enumerate(self.content): # Comments matching. search = re.search(r"^\s*[{0}](?P<comment>.+)$".format("".join(self.__commentLimiters)), line) if search: if not stripComments: comment = namespaces and foundations.namespace.setNamespace(section, "{0}{1}".format( self.__commentMarker, commentId), self.__namespaceSplitter) or \ "{0}{1}".format(self.__commentMarker, commentId) self.__comments[comment] = {"id": commentId, "content": stripWhitespaces and \ search.group( "comment").strip() or search.group( "comment")} commentId += 1 continue # Sections matching. search = re.search(r"^\s*\[(?P<section>.+)\]\s*$", line) if search: section = stripWhitespaces and search.group("section").strip() or search.group("section") if not self.__preserveOrder: attributes = {} else: attributes = OrderedDict() rawContent = [] continue if section in rawSections: rawContent.append(line) attributes[self.__rawSectionContentIdentifier] = rawContent else: # Empty line matching. search = re.search(r"^\s*$", line) if search: continue # Attributes matching. search = re.search(r"^(?P<attribute>.+?)[{0}](?P<value>.+)$".format("".join(self.__splitters)), line) \ or re.search(r"^(?P<attribute>.+?)[{0}]\s*$".format("".join(self.__splitters)), line) if search: attribute = search.group("attribute").strip() if stripWhitespaces else search.group("attribute") attribute = foundations.namespace.setNamespace(section, attribute, self.__namespaceSplitter) \ if namespaces else attribute if len(search.groups()) == 2: value = search.group("value").strip() if stripWhitespaces else search.group("value") attributes[attribute] = value.strip("".join(self.__quotationMarkers)) \ if stripQuotationMarkers else value else: attributes[attribute] = None else: self.__parsingErrors.append(foundations.exceptions.AttributeStructureParsingError( "Attribute structure is invalid: {0}".format(line), i + 1)) self.__sections[section] = attributes LOGGER.debug("> Sections: '{0}'.".format(self.__sections)) LOGGER.debug("> '{0}' file parsing done!".format(self.path)) if self.__parsingErrors and raiseParsingErrors: raise foundations.exceptions.FileStructureParsingError( "{0} | '{1}' structure is invalid, parsing exceptions occured!".format(self.__class__.__name__, self.path)) return self def sectionExists(self, section): """ Checks if given section exists. Usage:: >>> content = ["[Section A]\\n", "; Comment.\\n", "Attribute 1 = \\"Value A\\"\\n", "\\n", \ "[Section B]\\n", "Attribute 2 = \\"Value B\\"\\n"] >>> sectionsFileParser = SectionsFileParser() >>> sectionsFileParser.content = content >>> sectionsFileParser.parse() <foundations.parsers.SectionsFileParser object at 0x845683844> >>> sectionsFileParser.sectionExists("Section A") True >>> sectionsFileParser.sectionExists("Section C") False :param section: Section to check existence. :type section: unicode :return: Section existence. :rtype: bool """ if section in self.__sections: LOGGER.debug("> '{0}' section exists in '{1}'.".format(section, self)) return True else: LOGGER.debug("> '{0}' section doesn't exists in '{1}'.".format(section, self)) return False def attributeExists(self, attribute, section): """ Checks if given attribute exists. Usage:: >>> content = ["[Section A]\\n", "; Comment.\\n", "Attribute 1 = \\"Value A\\"\\n", "\\n", \ "[Section B]\\n", "Attribute 2 = \\"Value B\\"\\n"] >>> sectionsFileParser = SectionsFileParser() >>> sectionsFileParser.content = content >>> sectionsFileParser.parse() <foundations.parsers.SectionsFileParser object at 0x234564563> >>> sectionsFileParser.attributeExists("Attribute 1", "Section A") True >>> sectionsFileParser.attributeExists("Attribute 2", "Section A") False :param attribute: Attribute to check existence. :type attribute: unicode :param section: Section to search attribute into. :type section: unicode :return: Attribute existence. :rtype: bool """ if foundations.namespace.removeNamespace(attribute, rootOnly=True) in self.getAttributes(section, stripNamespaces=True): LOGGER.debug("> '{0}' attribute exists in '{1}' section.".format(attribute, section)) return True else: LOGGER.debug("> '{0}' attribute doesn't exists in '{1}' section.".format(attribute, section)) return False def getAttributes(self, section, stripNamespaces=False): """ Returns given section attributes. Usage:: >>> content = ["[Section A]\\n", "; Comment.\\n", "Attribute 1 = \\"Value A\\"\\n", "\\n", \ "[Section B]\\n", "Attribute 2 = \\"Value B\\"\\n"] >>> sectionsFileParser = SectionsFileParser() >>> sectionsFileParser.content = content >>> sectionsFileParser.parse() <foundations.parsers.SectionsFileParser object at 0x125698322> >>> sectionsFileParser.getAttributes("Section A") OrderedDict([(u'Section A|Attribute 1', u'Value A')]) >>> sectionsFileParser.preserveOrder=False >>> sectionsFileParser.getAttributes("Section A") {u'Section A|Attribute 1': u'Value A'} >>> sectionsFileParser.preserveOrder=True >>> sectionsFileParser.getAttributes("Section A", stripNamespaces=True) OrderedDict([(u'Attribute 1', u'Value A')]) :param section: Section containing the requested attributes. :type section: unicode :param stripNamespaces: Strip namespaces while retrieving attributes. :type stripNamespaces: bool :return: Attributes. :rtype: OrderedDict or dict """ LOGGER.debug("> Getting section '{0}' attributes.".format(section)) attributes = OrderedDict() if self.__preserveOrder else dict() if not self.sectionExists(section): return attributes if stripNamespaces: for attribute, value in self.__sections[section].iteritems(): attributes[foundations.namespace.removeNamespace(attribute, rootOnly=True)] = value else: attributes.update(self.__sections[section]) LOGGER.debug("> Attributes: '{0}'.".format(attributes)) return attributes def getAllAttributes(self): """ Returns all sections attributes. Usage:: >>> content = ["[Section A]\\n", "; Comment.\\n", "Attribute 1 = \\"Value A\\"\\n", "\\n", \ "[Section B]\\n", "Attribute 2 = \\"Value B\\"\\n"] >>> sectionsFileParser = SectionsFileParser() >>> sectionsFileParser.content = content >>> sectionsFileParser.parse() <foundations.parsers.SectionsFileParser object at 0x845683844> >>> sectionsFileParser.getAllAttributes() OrderedDict([(u'Section A|Attribute 1', u'Value A'), (u'Section B|Attribute 2', u'Value B')]) >>> sectionsFileParser.preserveOrder=False >>> sectionsFileParser.getAllAttributes() {u'Section B|Attribute 2': u'Value B', u'Section A|Attribute 1': u'Value A'} :return: All sections / files attributes. :rtype: OrderedDict or dict """ allAttributes = OrderedDict() if self.__preserveOrder else dict() for attributes in self.__sections.itervalues(): for attribute, value in attributes.iteritems(): allAttributes[attribute] = value return allAttributes @foundations.exceptions.handleExceptions(foundations.exceptions.FileStructureParsingError) def getValue(self, attribute, section, default=""): """ Returns requested attribute value. Usage:: >>> content = ["[Section A]\\n", "; Comment.\\n", "Attribute 1 = \\"Value A\\"\\n", "\\n", \ "[Section B]\\n", "Attribute 2 = \\"Value B\\"\\n"] >>> sectionsFileParser = SectionsFileParser() >>> sectionsFileParser.content = content >>> sectionsFileParser.parse() <foundations.parsers.SectionsFileParser object at 0x679302423> >>> sectionsFileParser.getValue("Attribute 1", "Section A") u'Value A' :param attribute: Attribute name. :type attribute: unicode :param section: Section containing the searched attribute. :type section: unicode :param default: Default return value. :type default: object :return: Attribute value. :rtype: unicode """ if not self.attributeExists(attribute, section): return default if attribute in self.__sections[section]: value = self.__sections[section][attribute] elif foundations.namespace.setNamespace(section, attribute) in self.__sections[section]: value = self.__sections[section][foundations.namespace.setNamespace(section, attribute)] LOGGER.debug("> Attribute: '{0}', value: '{1}'.".format(attribute, value)) return value def setValue(self, attribute, section, value): """ Sets requested attribute value. Usage:: >>> content = ["[Section A]\\n", "; Comment.\\n", "Attribute 1 = \\"Value A\\"\\n", "\\n", \ "[Section B]\\n", "Attribute 2 = \\"Value B\\"\\n"] >>> sectionsFileParser = SectionsFileParser() >>> sectionsFileParser.content = content >>> sectionsFileParser.parse() <foundations.parsers.SectionsFileParser object at 0x109304209> >>> sectionsFileParser.setValue("Attribute 3", "Section C", "Value C") True :param attribute: Attribute name. :type attribute: unicode :param section: Section containing the searched attribute. :type section: unicode :param value: Attribute value. :type value: object :return: Definition success. :rtype: bool """ if not self.sectionExists(section): LOGGER.debug("> Adding '{0}' section.".format(section)) self.__sections[section] = OrderedDict() if self.__preserveOrder else dict() self.__sections[section][attribute] = value return True def write(self, namespaces=False, splitter="=", commentLimiter=(";"), spacesAroundSplitter=True, spaceAfterCommentLimiter=True): """ Writes defined file using :obj:`SectionsFileParser.sections` and :obj:`SectionsFileParser.comments` class properties content. Usage:: >>> sections = {"Section A": {"Section A|Attribute 1": "Value A"}, \ "Section B": {"Section B|Attribute 2": "Value B"}} >>> sectionsFileParser = SectionsFileParser("SectionsFile.rc") >>> sectionsFileParser.sections = sections >>> sectionsFileParser.write() True >>> sectionsFileParser.read() u'[Section A]\\nAttribute 1 = Value A\\n\\n[Section B]\\nAttribute 2 = Value B\\n' :param namespaces: Attributes are namespaced. :type namespaces: bool :param splitter: Splitter character. :type splitter: unicode :param commentLimiter: Comment limiter character. :type commentLimiter: unicode :param spacesAroundSplitter: Spaces around attributes and value splitters. :type spacesAroundSplitter: bool :param spaceAfterCommentLimiter: Space after comments limiter. :type spaceAfterCommentLimiter: bool :return: Method success. :rtype: bool """ self.uncache() LOGGER.debug("> Setting '{0}' file content.".format(self.path)) attributeTemplate = "{{0}} {0} {{1}}\n".format(splitter) if spacesAroundSplitter else \ "{{0}}{0}{{1}}\n".format(splitter) attributeTemplate = foundations.strings.replace(attributeTemplate, {"{{" : "{", "}}" : "}"}) commentTemplate = spaceAfterCommentLimiter and "{0} {{0}}\n".format(commentLimiter) or \ "{0}{{0}}\n".format(commentLimiter) if self.__defaultsSection in self.__sections: LOGGER.debug("> Appending '{0}' default section.".format(self.__defaultsSection)) if self.__comments: for comment, value in self.__comments.iteritems(): if self.__defaultsSection in comment: value = value["content"] or "" LOGGER.debug("> Appending '{0}' comment with '{1}' value.".format(comment, value)) self.content.append(commentTemplate.format(value)) for attribute, value in self.__sections[self.__defaultsSection].iteritems(): attribute = namespaces and attribute or foundations.namespace.removeNamespace(attribute, self.__namespaceSplitter, rootOnly=True) value = value or "" LOGGER.debug("> Appending '{0}' attribute with '{1}' value.".format(attribute, value)) self.content.append(attributeTemplate.format(attribute, value)) self.content.append("\n") for i, section in enumerate(self.__sections): LOGGER.debug("> Appending '{0}' section.".format(section)) self.content.append("[{0}]\n".format(section)) if self.__comments: for comment, value in self.__comments.iteritems(): if section in comment: value = value["content"] or "" LOGGER.debug("> Appending '{0}' comment with '{1}' value.".format(comment, value)) self.content.append(commentTemplate.format(value)) for attribute, value in self.__sections[section].iteritems(): if foundations.namespace.removeNamespace(attribute) == self.__rawSectionContentIdentifier: LOGGER.debug("> Appending '{0}' raw section content.".format(section)) for line in value: self.content.append(line) else: LOGGER.debug("> Appending '{0}' section.".format(section)) attribute = namespaces and attribute or foundations.namespace.removeNamespace(attribute, self.__namespaceSplitter, rootOnly=True) value = value or "" LOGGER.debug("> Appending '{0}' attribute with '{1}' value.".format(attribute, value)) self.content.append(attributeTemplate.format(attribute, value)) if i != len(self.__sections) - 1: self.content.append("\n") foundations.io.File.write(self) return True
def __setitem__(self, key, value): self.pop(key, None) OrderedDict.__setitem__(self, key, value)
def __setitem__(self, key, value): if key not in self: OrderedDict.__setitem__(self, key, [value]) else: OrderedDict.__getitem__(self, key).append(value)
def __setitem__(self, key, val): if type(val) is StringType: val = self.handleBackTicks(val) OrderedDict.__setitem__(self, key, val)