-
Piotr Maślanka authored
* add SelectListener * add SelectListener * test out select listener * fix tests * fix tests * fix tests * fix tests * fix tests * refactor * refactor * more secure registering in epoll listener * more secure registering in epoll listener, v1.1.1 * reduced timeout for select listener * refactor * refactor * refactor * got rid of monotonic dependency for Python 3.x * instantiate listener_class * daemonize the thread in constructor * daemonize the thread in constructor * refactor * refactor * refactor * refactor * more refactor * more refactor * more refactor * more refactor * don't overwrite client data * run these tests verbose * run these tests verbose * ImportError fix * fix tests for monotonic
Unverifiede49f09c4
xml_fields.py 3.08 KiB
# coding=UTF-8
from __future__ import print_function, absolute_import, division
import six
class _Required(object):
"""Only a placeholder to tell apart None default values from required fields"""
def nop(x):
return x
def get_tag_child(elem, tag):
return [e for e in list(elem) if e.tag == tag]
__all__ = [
'_name', '_docs', 'ComputedField', 'ValueField', 'SimpleField',
'_docs_with_label', 'get_tag_child', 'ChildField'
]
class BaseField(object):
"""Base field object"""
def set(self, obj, elem):
obj.__dict__[self.field_name] = self.find(elem)
def __init__(self, field_name):
self.field_name = field_name
def find(self, elem):
raise NotImplementedError('Abstract method!')
class ComputedField(BaseField):
"""
There's no corresponding XML attribute name - value must
be computed from element
"""
def __init__(self, field_name, find_fun):
super(ComputedField, self).__init__(field_name)
self.find = find_fun
class ValueField(BaseField):
"""
Can hide under a pick of different XML attribute names.
Has a type, can have a default value.
"""
def __init__(self, xml_names, field_name, field_type=nop,
default=_Required):
if not isinstance(xml_names, tuple):
xml_names = (xml_names,)
self.xml_names = xml_names
assert field_type is not None
self.field_name = field_name
self.field_type = field_type
self.default = default
def find(self, elem):
return self.field_type(self._find(elem))
def _find(self, elem):
xmln = [xmln for xmln in self.xml_names if xmln in elem.attrib]
if xmln:
return elem.attrib[xmln[0]]
else:
if self.default is _Required:
raise TypeError(
'Did not find field %s in elem tag %s, looked for names %s' % (
self.field_name, elem.tag, self.xml_names))
else:
return self.default
class SimpleField(ValueField):
"""XML attribute is the same as name, has a type and can be default"""
def __init__(self, name, field_type=nop, default=_Required):
super(SimpleField, self).__init__(name, name, field_type, default)
class ChildField(ComputedField):
"""
List of other properties
"""
def __init__(self, name, xml_tag, fun, post_exec=nop):
super(ChildField, self).__init__(name, lambda elem: \
post_exec([fun(c) for c in get_tag_child(elem, xml_tag)]))
def get_docs(elem, label):
"""Parse an XML element. Return documentation"""
for kid in list(elem):
if kid.tag == 'rule':
return get_docs(kid, False)
s = kid.text.strip().split('\n')
return u'\n'.join([u.strip() for u in s if len(u.strip()) > 0])
if label:
return elem.attrib.get('label', None)
_name = SimpleField('name', six.text_type)
_docs = ComputedField('docs', lambda elem: get_docs(elem, False))
_docs_with_label = ComputedField('docs', lambda elem: get_docs(elem, True))