* fix: do not raise error when encoding/formatting an optional class elt.

* cleanup
* make autoxml pass the basic tests
This commit is contained in:
Eray Özkural
2005-09-28 13:43:29 +00:00
parent 5b4c7ad077
commit 30d8dff364
2 changed files with 30 additions and 39 deletions
+26 -34
View File
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# #
# Copyright (C) 2005, TUBITAK/UEKAE # Copyright (C) 2005, TUBITAK/UEKAE
# #
@@ -160,7 +161,7 @@ class autoxml(type):
def __init__(cls, name, bases, dict): def __init__(cls, name, bases, dict):
"""entry point for metaclass code""" """entry point for metaclass code"""
print 'generating class', name #print 'generating class', name
# add XmlFile as one of the superclasses, we're smart # add XmlFile as one of the superclasses, we're smart
bases = list(bases) bases = list(bases)
@@ -227,55 +228,42 @@ class autoxml(type):
def gen_attr_member(cls, attr): def gen_attr_member(cls, attr):
"""generate readers and writers for an attribute member""" """generate readers and writers for an attribute member"""
print 'attr:', attr #print 'attr:', attr
spec = getattr(cls, 'a_' + attr) spec = getattr(cls, 'a_' + attr)
tag_type = spec[0] tag_type = spec[0]
assert type(tag_type) == type(type) assert type(tag_type) == type(type)
def readtext(node, attr): def readtext(node, attr):
return getNodeAttribute(node, attr) return getNodeAttribute(node, attr)
def createnode(xml, attr_name):
print 'create attr', attr_name
return xml.newAttribute(attr_name) # create an attribute node
def writetext(xml, node, attr, text): def writetext(xml, node, attr, text):
print 'write attr', attr, text #print 'write attr', attr, text
node.setAttribute(attr, text) node.setAttribute(attr, text)
anonfuns = cls.gen_anon_basic(attr, spec, readtext, createnode, writetext) anonfuns = cls.gen_anon_basic(attr, spec, readtext, writetext)
def mergetext(node, newattr): return cls.gen_named_comp(attr, spec, anonfuns)
print 'merge attr', node, attr
node.setAttributeNode(newattr)
return cls.gen_named_comp(attr, spec, anonfuns, mergetext)
def gen_tag_member(cls, tag): def gen_tag_member(cls, tag):
"""generate helper funs for tag member of class""" """generate helper funs for tag member of class"""
print 'tag:', tag #print 'tag:', tag
spec = getattr(cls, 't_' + tag) spec = getattr(cls, 't_' + tag)
anonfuns = cls.gen_tag(tag, spec) anonfuns = cls.gen_tag(tag, spec)
def mergetext(node, newnode): return cls.gen_named_comp(tag, spec, anonfuns)
print 'merge tag', node, newnode
node.appendChild(newnode)
return cls.gen_named_comp(tag, spec, anonfuns, mergetext)
def gen_tag(cls, tag, spec): def gen_tag(cls, tag, spec):
"""generate readers and writers for the tag""" """generate readers and writers for the tag"""
tag_type = spec[0] tag_type = spec[0]
if type(tag_type) is types.TypeType: if type(tag_type) is types.TypeType:
def readtext(node, tagpath): def readtext(node, tagpath):
print 'read tag', node, tagpath #print 'read tag', node, tagpath
return getNodeText(node, tagpath) return getNodeText(node, tagpath)
def createnode(xml, tag):
print 'create node', tag
return xml.newNode(tag)
def writetext(xml, node, tagpath, text): def writetext(xml, node, tagpath, text):
print 'write tag', node, tagpath, text #print 'write tag', node, tagpath, text
xml.addTextNodeUnder(node, tagpath, text) xml.addTextNodeUnder(node, tagpath, text)
return cls.gen_anon_basic(tag, spec, readtext, return cls.gen_anon_basic(tag, spec, readtext, writetext)
createnode, writetext)
elif type(tag_type) is types.ListType: elif type(tag_type) is types.ListType:
return cls.gen_list_tag(tag, spec) return cls.gen_list_tag(tag, spec)
elif type(tag_type) is autoxml or type(tag_type) is types.ClassType: elif type(tag_type) is autoxml or type(tag_type) is types.ClassType:
return cls.gen_class_tag(tag, spec) return cls.gen_class_tag(tag, spec)
def gen_named_comp(cls, token, spec, anonfuns, mergetext): def gen_named_comp(cls, token, spec, anonfuns):
"""generate a named component tag/attr. a decoration of """generate a named component tag/attr. a decoration of
anonymous functions that do not bind to variable names""" anonymous functions that do not bind to variable names"""
name = cls.mixed_case(token) name = cls.mixed_case(token)
@@ -345,7 +333,7 @@ class autoxml(type):
# the token # the token
return name, token_type, req, path return name, token_type, req, path
def gen_anon_basic(cls, token, spec, readtext, createnode, writetext): def gen_anon_basic(cls, token, spec, readtext, writetext):
"""Generate a tag or attribute with one of the basic """Generate a tag or attribute with one of the basic
types like integer. This has got to be pretty generic types like integer. This has got to be pretty generic
so that we can invoke it from the complex types such as Class so that we can invoke it from the complex types such as Class
@@ -361,7 +349,7 @@ class autoxml(type):
def decode(node): def decode(node):
"""decode from DOM node, the value, watching the spec""" """decode from DOM node, the value, watching the spec"""
text = readtext(node, token) text = readtext(node, token)
print 'read text ', text #print 'read text ', text
if text: if text:
try: try:
value = autoxml.basic_cons_map[token_type](text) value = autoxml.basic_cons_map[token_type](text)
@@ -377,7 +365,6 @@ class autoxml(type):
def encode(xml, node, value): def encode(xml, node, value):
"""encode given value inside DOM node""" """encode given value inside DOM node"""
if value: if value:
#node = createnode(xml, token)
writetext(xml, node, token, str(value)) writetext(xml, node, token, str(value))
return node return node
else: else:
@@ -422,16 +409,22 @@ class autoxml(type):
classnode = node.ownerDocument.createElement(tag) classnode = node.ownerDocument.createElement(tag)
obj.encode(xml, classnode) obj.encode(xml, classnode)
node.appendChild(classnode) node.appendChild(classnode)
return
except Error: except Error:
raise Error('Object cannot be encoded') if req == mandatory:
# note: we can receive an error if obj has no content
raise Error('Object cannot be encoded')
else: else:
if req == mandatory: if req == mandatory:
raise Error('Mandatory argument not available') raise Error('Mandatory argument not available')
def format(obj): def format(obj):
return obj.format() try:
return obj.format()
except Error:
if req == mandatory:
raise Error('Mandatory argument not available')
else:
return ""
return (init, decode, encode, format) return (init, decode, encode, format)
def gen_list_tag(cls, tag, spec): def gen_list_tag(cls, tag, spec):
@@ -451,8 +444,7 @@ class autoxml(type):
def decode(node): def decode(node):
l = [] l = []
nodes = getAllNodes(node, tag + '/' + comp_tag) nodes = getAllNodes(node, tag + '/' + comp_tag)
print node, tag + '/' + comp_tag #print node, tag + '/' + comp_tag, nodes
print 'F U', nodes
if len(nodes) is 0 and req is mandatory: if len(nodes) is 0 and req is mandatory:
raise Error('Mandatory list empty') raise Error('Mandatory list empty')
for node in nodes: for node in nodes:
@@ -462,7 +454,7 @@ class autoxml(type):
return l return l
def encode(xml, node, l): def encode(xml, node, l):
if len(l) > 0: if l and len(l) > 0:
listnode = xml.newNode(tag) listnode = xml.newNode(tag)
for item in l: for item in l:
encode_item(xml, listnode, item) encode_item(xml, listnode, item)
+4 -5
View File
@@ -32,7 +32,7 @@ class XmlFileTestCase(unittest.TestCase):
__metaclass__ = xmlfile.autoxml __metaclass__ = xmlfile.autoxml
t_BirthDate = [types.StringType, xmlfile.mandatory] t_BirthDate = [types.StringType, xmlfile.mandatory]
t_Interest = [types.StringType, xmlfile.optional] t_Interest = [types.StringType, xmlfile.optional]
#t_CodesWith = [ [types.StringType], xmlfile.optional, 'Person'] t_CodesWith = [ [types.StringType], xmlfile.optional, 'Person']
class A: class A:
__metaclass__ = xmlfile.autoxml __metaclass__ = xmlfile.autoxml
@@ -58,17 +58,16 @@ class XmlFileTestCase(unittest.TestCase):
xml = xmlfile.XmlFile('A') xml = xmlfile.XmlFile('A')
xml.newDOM() xml.newDOM()
a.encode(xml, xml.rootNode()) a.encode(xml, xml.rootNode())
#xml.rootNode().appendChild(node) xml.rootNode().appendChild(node)
xml.writexml('/tmp/a.xml') xml.writexml('/tmp/a.xml')
print '/tmp/a.xml written' #print '/tmp/a.xml written'
return
xml = xmlfile.XmlFile('A') xml = xmlfile.XmlFile('A')
a2 = A() a2 = A()
a2.name = "Baris Metin" a2.name = "Baris Metin"
a2.email = "baris@uludag.org.tr" a2.email = "baris@uludag.org.tr"
a2.href = 'http://cekirdek.uludag.org.tr/~baris' a2.href = 'http://cekirdek.uludag.org.tr/~baris'
a2.projects = [ 'pisi', 'tasma', 'plasma' ] a2.projects = [ 'pisi', 'tasma', 'plasma' ]
a2.encode(xml) a2.encode(xml, xml.rootNode())
xml.writexml('/tmp/a2.xml') xml.writexml('/tmp/a2.xml')
string = a2.format() string = a2.format()