from __future__ import absolute_import
# Copyright (c) 2010-2019 openpyxl
"""
Generic serialisable classes
"""
from .base import (
Convertible,
Bool,
Descriptor,
NoneSet,
MinMax,
Set,
Float,
Integer,
String,
Text,
)
from .sequence import Sequence
from openpyxl.compat import safe_string
from openpyxl.xml.functions import Element, localname, whitespace
[docs]class Nested(Descriptor):
nested = True
attribute = "val"
def __set__(self, instance, value):
if hasattr(value, "tag"):
tag = localname(value)
if tag != self.name:
raise ValueError("Tag does not match attribute")
value = self.from_tree(value)
super(Nested, self).__set__(instance, value)
[docs] def from_tree(self, node):
return node.get(self.attribute)
[docs] def to_tree(self, tagname=None, value=None, namespace=None):
namespace = getattr(self, "namespace", namespace)
if value is not None:
if namespace is not None:
tagname = "{%s}%s" % (namespace, tagname)
value = safe_string(value)
return Element(tagname, {self.attribute:value})
[docs]class NestedValue(Nested, Convertible):
"""
Nested tag storing the value on the 'val' attribute
"""
pass
[docs]class NestedText(NestedValue):
"""
Represents any nested tag with the value as the contents of the tag
"""
[docs] def from_tree(self, node):
return node.text
[docs] def to_tree(self, tagname=None, value=None, namespace=None):
namespace = getattr(self, "namespace", namespace)
if value is not None:
if namespace is not None:
tagname = "{%s}%s" % (namespace, tagname)
el = Element(tagname)
el.text = safe_string(value)
whitespace(el)
return el
[docs]class NestedFloat(NestedValue, Float):
pass
[docs]class NestedInteger(NestedValue, Integer):
pass
[docs]class NestedString(NestedValue, String):
pass
[docs]class NestedBool(NestedValue, Bool):
[docs] def from_tree(self, node):
return node.get("val", True)
[docs]class NestedNoneSet(Nested, NoneSet):
pass
[docs]class NestedSet(Nested, Set):
pass
[docs]class NestedMinMax(Nested, MinMax):
pass
[docs]class EmptyTag(Nested, Bool):
"""
Boolean if a tag exists or not.
"""
[docs] def from_tree(self, node):
return True
[docs] def to_tree(self, tagname=None, value=None, namespace=None):
if value:
namespace = getattr(self, "namespace", namespace)
if namespace is not None:
tagname = "{%s}%s" % (namespace, tagname)
return Element(tagname)