Now the various objects attributes are derived directly from the data with which they're initialized.
This commit is contained in:
parent
6abccdc728
commit
9be618cd8c
|
@ -68,7 +68,17 @@ class ErrorHandler(object):
|
||||||
|
|
||||||
|
|
||||||
class Document(dict):
|
class Document(dict):
|
||||||
pass
|
_attr_types = {}
|
||||||
|
"Override the types from the document"
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
type = self._attr_types.get(name, lambda x: x)
|
||||||
|
attr_name = '@' + name
|
||||||
|
try:
|
||||||
|
val = self[name] if name in self else self[attr_name]
|
||||||
|
except KeyError:
|
||||||
|
raise AttributeError(name)
|
||||||
|
return type(val)
|
||||||
|
|
||||||
|
|
||||||
class Result(ErrorHandler, Document):
|
class Result(ErrorHandler, Document):
|
||||||
|
@ -140,60 +150,74 @@ class Image(Document):
|
||||||
"""
|
"""
|
||||||
Holds information about an image included with an answer.
|
Holds information about an image included with an answer.
|
||||||
"""
|
"""
|
||||||
def __init__(self, *args, **kwargs):
|
_attr_types = dict(
|
||||||
super(Image, self).__init__(*args, **kwargs)
|
height=int,
|
||||||
self.title = self['@title']
|
width=int,
|
||||||
self.alt = self['@alt']
|
)
|
||||||
self.height = self['@height']
|
|
||||||
self.width = self['@width']
|
@classmethod
|
||||||
self.src = self['@src']
|
def from_doc(cls, doc):
|
||||||
|
"""
|
||||||
|
Load images from the xmltodictresult. Always return
|
||||||
|
a list, even if the result is a singleton.
|
||||||
|
"""
|
||||||
|
if type(doc) != list:
|
||||||
|
doc = [doc]
|
||||||
|
return list(map(Image, doc))
|
||||||
|
|
||||||
|
|
||||||
class Subpod(Document):
|
class Subpod(Document):
|
||||||
"""
|
"""
|
||||||
Holds a specific answer or additional information relevant to said answer.
|
Holds a specific answer or additional information relevant to said answer.
|
||||||
"""
|
"""
|
||||||
def __init__(self, *args, **kwargs):
|
_attr_types = dict(
|
||||||
super(Subpod, self).__init__(*args, **kwargs)
|
img=Image.from_doc,
|
||||||
self.title = self['@title']
|
)
|
||||||
self.text = self['plaintext']
|
|
||||||
self.img = self['img']
|
@classmethod
|
||||||
# Allow images to be accessed in a consistent way,
|
def from_doc(cls, doc):
|
||||||
# as a list, regardless of how many there are.
|
"""
|
||||||
if type(self.img) != list:
|
Load subpods from the xmltodict result. Always return
|
||||||
self.img = [self.img]
|
a list, even if the result is a singleton.
|
||||||
self.img = list(map(Image, self.img))
|
"""
|
||||||
|
if type(doc) != list:
|
||||||
|
doc = [doc]
|
||||||
|
return list(map(cls, doc))
|
||||||
|
|
||||||
|
|
||||||
|
def xml_bool(str_val):
|
||||||
|
return (
|
||||||
|
bool(int(str_val))
|
||||||
|
if str_val.isdigit() else
|
||||||
|
str_val.lower() != 'true'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Pod(ErrorHandler, Document):
|
class Pod(ErrorHandler, Document):
|
||||||
"""
|
"""
|
||||||
Groups answers and information contextualizing those answers.
|
Groups answers and information contextualizing those answers.
|
||||||
"""
|
"""
|
||||||
|
_attr_types = dict(
|
||||||
|
position=float,
|
||||||
|
numsubpods=int,
|
||||||
|
subpod=Subpod.from_doc,
|
||||||
|
)
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(Pod, self).__init__(*args, **kwargs)
|
super(Pod, self).__init__(*args, **kwargs)
|
||||||
self.error = self['@error']
|
|
||||||
self._handle_error(self)
|
self._handle_error(self)
|
||||||
self.title = self['@title']
|
|
||||||
self.scanner = self['@scanner']
|
@property
|
||||||
self.id = self['@id']
|
def primary(self):
|
||||||
self.position = float(self['@position'])
|
return '@primary' in self and xml_bool(self['@primary'])
|
||||||
self.number_of_subpods = int(self['@numsubpods'])
|
|
||||||
self.subpods = self['subpod']
|
|
||||||
# Allow subpods to be accessed in a consistent way,
|
|
||||||
# as a list, regardless of how many there are.
|
|
||||||
if type(self.subpods) != list:
|
|
||||||
self.subpods = [self.subpods]
|
|
||||||
self.subpods = list(map(Subpod, self.subpods))
|
|
||||||
self.primary = '@primary' in self and self['@primary'] != 'false'
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def texts(self):
|
def texts(self):
|
||||||
"""
|
"""
|
||||||
The text from each subpod in this pod as a list.
|
The text from each subpod in this pod as a list.
|
||||||
"""
|
"""
|
||||||
return [subpod.text for subpod in self.subpods]
|
return [subpod.plaintext for subpod in self.subpod]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def text(self):
|
def text(self):
|
||||||
return next(iter(self.subpods)).text
|
return next(iter(self.subpod)).plaintext
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,11 @@ def test_properties(temp_result):
|
||||||
assert len(info) == len(pods) + len(warnings) + len(assumptions)
|
assert len(info) == len(pods) + len(warnings) + len(assumptions)
|
||||||
|
|
||||||
|
|
||||||
def test_pod_position_is_float(temp_result):
|
def test_pod_attributes(temp_result):
|
||||||
pod = next(temp_result.pods)
|
pod = next(temp_result.pods)
|
||||||
assert isinstance(pod.position, float)
|
assert isinstance(pod.position, float)
|
||||||
|
assert isinstance(pod.id, str)
|
||||||
|
assert isinstance(pod.subpod[0].img[0].height, int)
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_app_id():
|
def test_invalid_app_id():
|
||||||
|
|
Loading…
Reference in New Issue
Block a user