source: orange-bioinformatics/_bioinformatics/obiKEGG/entry/__init__.py @ 1734:91d14dd2cf0e

Revision 1734:91d14dd2cf0e, 4.5 KB checked in by Ales Erjavec <ales.erjavec@…>, 14 months ago (diff)

obiKEGG code style fixes.

RevLine 
[1532]1"""
[1733]2DBGET entry
[1532]3"""
4from __future__ import absolute_import
5
6__all__ = ["parser", "fields"]
7
8from collections import defaultdict
9
10from . import fields
11from .parser import DBGETEntryParser
12
[1734]13
[1532]14def entry_decorate(cls):
[1734]15    """
16    Decorate the DBEntry subclass with properties for accessing
[1532]17    the fields through the 'DBField._convert' interface
[1734]18
[1532]19    """
20    reserved_names_map = {"class": "class_", "def": "def_"}
[1734]21
[1532]22    def construct_one(name):
23        def get(self):
24            field = getattr(self, name, None)
25            if field is not None:
26                return field._convert()
27            else:
28                return None
29        return property(get, doc=name)
[1734]30
[1532]31    def construct_multiple(name):
32        def get(self):
33            field = getattr(self, name, None)
34            if field is not None:
35                return [f._convert() for f in field]
36            else:
37                return None
38        return property(get, doc=name)
[1734]39
[1532]40    for name, field in cls.FIELDS:
41        name_lower = name.lower()
42        if not hasattr(cls, name_lower):
43            if name in cls.MULTIPLE_FIELDS:
44                prop = construct_multiple(name)
45            else:
46                prop = construct_one(name)
47            setattr(cls, reserved_names_map.get(name_lower, name_lower), prop)
[1734]48
[1532]49    return cls
50
[1734]51
[1532]52class DBEntry(object):
53    """
[1734]54    A DBGET entry object.
55    """
56    FIELDS = [("ENTRY", fields.DBEntryField)]
[1532]57    MULTIPLE_FIELDS = []
[1734]58
[1532]59    def __init__(self, text=None):
60        self._sections = {}
61        if text is not None:
62            self.parse(text)
[1734]63
[1532]64    @property
65    def entry_key(self):
66        """ Primary entry key used for querying.
67        """
68        return self.entry.split(" ", 1)[0]
[1734]69
[1532]70    def parse(self, text):
71        parser = DBGETEntryParser()
72        gen = parser.parse_string(text)
73        field_constructors = dict(self.FIELDS)
[1734]74
[1532]75        current = None
76        current_subfield = None
77        entry_fields = []
78        for (event, title, text) in gen:
79            if event == DBGETEntryParser.SECTION_START:
80                if title in field_constructors:
81                    ftype = field_constructors[title]
82                else:
83                    ftype = fields.DBSimpleField
84                current = ftype(text)
85                if current.TITLE is None:
86                    current.TITLE = title
87            elif event == DBGETEntryParser.SECTION_END:
88                entry_fields.append(current)
89                current = None
90            elif event == DBGETEntryParser.SUBSECTION_START:
91                current_subfield = fields.DBSimpleField(text)
92                current_subfield.TITLE = title
93                if not isinstance(current, fields.DBFieldWithSubsections):
94                    # Upgrade simple fields to FieldWithSubsection
95                    new = fields.DBFieldWithSubsections(current.text)
96                    new.TITLE = current.TITLE
97                    current = new
[1734]98
[1532]99            elif event == DBGETEntryParser.SUBSECTION_END:
100                current.subsections.append(current_subfield)
101                current_subfield = None
102            elif event == DBGETEntryParser.TEXT:
103                if current_subfield is not None:
104                    current_subfield.text += text
105                elif current is not None:
106                    current.text += text
107            elif event == DBGETEntryParser.ENTRY_END:
108                break
[1734]109
[1532]110        self.fields = entry_fields
111        self._consolidate()
[1734]112
[1532]113    def _consolidate(self):
[1734]114        """
115        Update mapping to field entries.
[1532]116        """
117        registered_fields = dict(self.FIELDS)
118        multiple_fields = set(self.MULTIPLE_FIELDS)
[1734]119
[1532]120        for field in self.fields:
121            title = field.TITLE
122            if title not in registered_fields:
123                import warnings
[1551]124                warnings.warn("Nonregisterd field %r in %r" % \
[1734]125                              (title, type(self)))
126
[1532]127            if title in multiple_fields:
128                if not hasattr(self, title):
129                    setattr(self, title, [])
130                getattr(self, title).append(field)
131            else:
132                setattr(self, title, field)
[1734]133
[1532]134    def __str__(self):
135        return self.format()
[1734]136
[1532]137    def format(self, section_indent=12):
[1734]138        return "".join(f.format(section_indent)
[1532]139                       for f in self.fields)
[1734]140
[1532]141    def get(self, key, default=None):
142        raise NotImplementedError
[1734]143
[1532]144        f = getattr(self, key, None)
145        if f is not None:
146            if key in self.MULTIPLE_FIELDS:
147                return [f.text for f in f]
148            else:
149                return f.text
150        else:
151            return None
Note: See TracBrowser for help on using the repository browser.